naspro
changeset 178:7169a8909d53 trunk naspro-0.2.0
Added Permafrost + small changes
line diff
1.1 --- a/naspro-bridges-bad/INSTALL Sun May 02 14:03:59 2010 +0300 1.2 +++ b/naspro-bridges-bad/INSTALL Sun May 02 14:19:58 2010 +0300 1.3 @@ -54,3 +54,5 @@ 1.4 And install with: 1.5 1.6 $ make install 1.7 + 1.8 +The generated Makefile supports DESTDIR.
2.1 --- a/naspro-core/CMakeLists.txt Sun May 02 14:03:59 2010 +0300 2.2 +++ b/naspro-core/CMakeLists.txt Sun May 02 14:19:58 2010 +0300 2.3 @@ -10,9 +10,7 @@ 2.4 include(FindPkgConfig) 2.5 pkg_check_modules(LV2 REQUIRED lv2core) 2.6 2.7 -include_directories(. ${LV2_INCLUDE_DIRS}) 2.8 - 2.9 -include_directories("${NACORE_SOURCE_DIR}" "${NACORE_SOURCE_DIR}/include") 2.10 +include_directories("${NACORE_SOURCE_DIR}" "${NACORE_SOURCE_DIR}/include" ${LV2_INCLUDE_DIRS}) 2.11 add_library(nacore SHARED ${NACORE_SOURCES}) 2.12 set_target_properties(nacore PROPERTIES VERSION 2.0.0 SOVERSION 2) 2.13 find_library(LIBDL dl)
3.1 --- a/naspro-core/INSTALL Sun May 02 14:03:59 2010 +0300 3.2 +++ b/naspro-core/INSTALL Sun May 02 14:19:58 2010 +0300 3.3 @@ -48,3 +48,5 @@ 3.4 And install with: 3.5 3.6 $ make install 3.7 + 3.8 +The generated Makefile supports DESTDIR.
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/permafrost/AUTHORS Sun May 02 14:19:58 2010 +0300 4.3 @@ -0,0 +1,1 @@ 4.4 +Stefano D'Angelo <zanga.mail@gmail.com>
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/permafrost/CMakeLists.txt Sun May 02 14:19:58 2010 +0300 5.3 @@ -0,0 +1,47 @@ 5.4 +cmake_minimum_required(VERSION 2.8) 5.5 + 5.6 +project(PERMAFROST) 5.7 + 5.8 +set(PERMAFROST_VERSION 0.2.0) 5.9 + 5.10 +set(PERMAFROST_SOURCES src/main.c src/util.c src/list.c src/expr.c src/scanner.c src/parser.c src/parser.tab.c src/macro.c src/schedule.c src/compile.c) 5.11 + 5.12 +include_directories("${PERMAFROST_SOURCE_DIR}") 5.13 + 5.14 +add_executable(permafrost ${PERMAFROST_SOURCES}) 5.15 +target_link_libraries(permafrost m) 5.16 + 5.17 +if (NOT DEFINED BINDIR_INSTALL) 5.18 + set(BINDIR_INSTALL bin) 5.19 +endif () 5.20 + 5.21 +if (NOT DEFINED DATADIR_INSTALL) 5.22 + set(DATADIR_INSTALL "${CMAKE_INSTALL_PREFIX}/share/permafrost") 5.23 +endif () 5.24 + 5.25 +configure_file("${PERMAFROST_SOURCE_DIR}/config.h.in" "${PERMAFROST_BINARY_DIR}/config.h" @ONLY) 5.26 + 5.27 +install(TARGETS permafrost DESTINATION "${BINDIR_INSTALL}") 5.28 +install(DIRECTORY "${PERMAFROST_SOURCE_DIR}/lib" DESTINATION "${DATADIR_INSTALL}") 5.29 + 5.30 +set(CPACK_PACKAGE_VERSION_MAJOR 0) 5.31 +set(CPACK_PACKAGE_VERSION_MINOR 2) 5.32 +set(CPACK_PACKAGE_VERSION_PATCH 0) 5.33 +set(CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}) 5.34 +set(CPACK_SOURCE_GENERATOR TGZ) 5.35 +set(CPACK_SOURCE_PACKAGE_FILE_NAME permafrost-${CPACK_PACKAGE_VERSION}) 5.36 +set(CPACK_SOURCE_IGNORE_FILES 5.37 + "^${PERMAFROST_BINARY_DIR}/CMakeCache.*" 5.38 + "^${PERMAFROST_BINARY_DIR}/CMakeFiles.*" 5.39 + "^${PERMAFROST_BINARY_DIR}/cmake.*" 5.40 + "^${PERMAFROST_BINARY_DIR}/install.*" 5.41 + "^${PERMAFROST_BINARY_DIR}/_CPack.*" 5.42 + "^${PERMAFROST_BINARY_DIR}/CPack.*" 5.43 + "^${PERMAFROST_BINARY_DIR}/Makefile$" 5.44 + "^${PERMAFROST_BINARY_DIR}/permafrost-.*" 5.45 + "^${PERMAFROST_BINARY_DIR}/config.h$" 5.46 + "^${PERMAFROST_BINARY_DIR}/.*\\\\.o$" 5.47 + "^${PERMAFROST_BINARY_DIR}/permafrost.*$" 5.48 +) 5.49 + 5.50 +include(CPack)
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/permafrost/COPYING Sun May 02 14:19:58 2010 +0300 6.3 @@ -0,0 +1,24 @@ 6.4 +Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 6.5 +All rights reserved. 6.6 + 6.7 +Redistribution and use in source and binary forms, with or without 6.8 +modification, are permitted provided that the following conditions 6.9 +are met: 6.10 + 1. Redistributions of source code must retain the above copyright 6.11 + notice, this list of conditions and the following disclaimer. 6.12 + 2. Redistributions in binary form must reproduce the above copyright 6.13 + notice, this list of conditions and the following disclaimer in the 6.14 + documentation and/or other materials provided with the distribution. 6.15 + 3. The name of the author may not be used to endorse or promote products 6.16 + derived from this software without specific prior written permission. 6.17 + 6.18 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 6.19 +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 6.20 +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 6.21 +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 6.22 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 6.23 +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 6.24 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 6.25 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 6.26 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 6.27 +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/permafrost/INSTALL Sun May 02 14:19:58 2010 +0300 7.3 @@ -0,0 +1,49 @@ 7.4 +Build and installation instructions 7.5 +=================================== 7.6 + 7.7 +Build-time requirements 7.8 +----------------------- 7.9 + 7.10 +* CMake >= 2.8.0 (http://www.cmake.org) 7.11 +* Some C compiler (only tested with gcc) 7.12 + 7.13 +Runtime requirements 7.14 +-------------------- 7.15 + 7.16 +A standard C library implementation (including math functions). 7.17 + 7.18 +Building 7.19 +-------- 7.20 + 7.21 +To configure the package use: 7.22 + 7.23 + $ cmake . 7.24 + 7.25 +or, if building in some other directory: 7.26 + 7.27 + $ cmake <top-level sources directory> 7.28 + 7.29 +You can specify installation directories like this: 7.30 + 7.31 + $ cmake -DVAR1=VALUE1 -DVAR2=VALUE2 ... 7.32 + 7.33 +If VALUE is a relative path, it is considered as relative to the prefix 7.34 +directory (CMAKE_INSTALL_PREFIX). 7.35 + 7.36 +The build system understands the following variables VARx: 7.37 + 7.38 + * CMAKE_INSTALL_PREFIX Installation prefix (the default value is determined 7.39 + by CMake) 7.40 + * BINDIR_INSTALL Where to put program executables (the default is bin) 7.41 + * DATADIR_INSTALL Where to put shared data files (the default is 7.42 + share/permafrost) 7.43 + 7.44 +Then, build with: 7.45 + 7.46 + $ make 7.47 + 7.48 +And install with: 7.49 + 7.50 + $ make install 7.51 + 7.52 +The generated Makefile supports DESTDIR.
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/permafrost/README Sun May 02 14:19:58 2010 +0300 8.3 @@ -0,0 +1,16 @@ 8.4 +Permafrost 8.5 +========== 8.6 + 8.7 +Permafrost is a DSP language designed with physics-based modeling in mind. 8.8 + 8.9 +This package contains a compiler for such language which generates C source code 8.10 +and RDF/Turtle data which constitute the basis of LV2 plugins. 8.11 + 8.12 +The syntax is not definitive and backwards compatibility will not be taken 8.13 +seriously in the next releases, yet the language already has some interesting 8.14 +features such as automatic scheduling, bidirectional ports, macroing and 8.15 +importing of C functions. 8.16 + 8.17 +The language is not documented, all there is available at the moment, apart from 8.18 +the source code of this compiler, is a set of examples in the examples 8.19 +directory you can take a look at.
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/permafrost/config.h.in Sun May 02 14:19:58 2010 +0300 9.3 @@ -0,0 +1,5 @@ 9.4 +#ifndef CONFIG_H 9.5 + 9.6 +#define PMF_LIB_DIR "@DATADIR_INSTALL@/lib/" 9.7 + 9.8 +#endif /* !CONFIG_H */
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/permafrost/examples/Amp-extra.ttl Sun May 02 14:19:58 2010 +0300 10.3 @@ -0,0 +1,15 @@ 10.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 10.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 10.6 + 10.7 +<http://www.example.com/Amp> 10.8 + doap:name "Amp" ; 10.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 10.10 + 10.11 +<http://www.example.com/Amp/ports/o> lv2:name "Output" . 10.12 + 10.13 +<http://www.example.com/Amp/ports/gain> lv2:name "Gain" ; 10.14 + lv2:minimum 0 ; 10.15 + lv2:maximum 10 ; 10.16 + lv2:default 1 . 10.17 + 10.18 +<http://www.example.com/Amp/ports/i> lv2:name "Input" .
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/permafrost/examples/Amp_dB-extra.ttl Sun May 02 14:19:58 2010 +0300 11.3 @@ -0,0 +1,15 @@ 11.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 11.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 11.6 + 11.7 +<http://www.example.com/Amp_dB> 11.8 + doap:name "Amp (dB)" ; 11.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 11.10 + 11.11 +<http://www.example.com/Amp_dB/ports/o> lv2:name "Output" . 11.12 + 11.13 +<http://www.example.com/Amp_dB/ports/gain_dB> lv2:name "Gain (dB)" ; 11.14 + lv2:minimum -100 ; 11.15 + lv2:maximum 10 ; 11.16 + lv2:default 0 . 11.17 + 11.18 +<http://www.example.com/Amp_dB/ports/i> lv2:name "Input" .
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/permafrost/examples/Arctan_waveshaper-extra.ttl Sun May 02 14:19:58 2010 +0300 12.3 @@ -0,0 +1,15 @@ 12.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 12.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 12.6 + 12.7 +<http://www.example.com/Arctan_waveshaper> 12.8 + doap:name "Arctan waveshaper" ; 12.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 12.10 + 12.11 +<http://www.example.com/Arctan_waveshaper/ports/o> lv2:name "Output" . 12.12 + 12.13 +<http://www.example.com/Arctan_waveshaper/ports/level> lv2:name "Level" ; 12.14 + lv2:minimum 1 ; 12.15 + lv2:maximum 100 ; 12.16 + lv2:default 1 . 12.17 + 12.18 +<http://www.example.com/Arctan_waveshaper/ports/i> lv2:name "Input" .
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/permafrost/examples/Comb_filter_max_10_secs-extra.ttl Sun May 02 14:19:58 2010 +0300 13.3 @@ -0,0 +1,20 @@ 13.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 13.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 13.6 + 13.7 +<http://www.example.com/Comb_filter_max_10_secs> 13.8 + doap:name "Comb filter (max 10 secs)" ; 13.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 13.10 + 13.11 +<http://www.example.com/Comb_filter_max_10_secs/ports/o> lv2:name "Output" . 13.12 + 13.13 +<http://www.example.com/Comb_filter_max_10_secs/ports/feedback> lv2:name "Feedback" ; 13.14 + lv2:minimum 0 ; 13.15 + lv2:maximum 1 ; 13.16 + lv2:default 0 . 13.17 + 13.18 +<http://www.example.com/Comb_filter_max_10_secs/ports/delay> lv2:name "Delay" ; 13.19 + lv2:minimum 0 ; 13.20 + lv2:maximum 10 ; 13.21 + lv2:default 1 . 13.22 + 13.23 +<http://www.example.com/Comb_filter_max_10_secs/ports/i> lv2:name "Input" .
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/permafrost/examples/Delay_10000_samples-extra.ttl Sun May 02 14:19:58 2010 +0300 14.3 @@ -0,0 +1,10 @@ 14.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 14.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 14.6 + 14.7 +<http://www.example.com/Delay_10000_samples> 14.8 + doap:name "10000 samples delay" ; 14.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 14.10 + 14.11 +<http://www.example.com/Delay_10000_samples/ports/o> lv2:name "Output" . 14.12 + 14.13 +<http://www.example.com/Delay_10000_samples/ports/i> lv2:name "Input" .
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/permafrost/examples/Delay_10_samples-extra.ttl Sun May 02 14:19:58 2010 +0300 15.3 @@ -0,0 +1,10 @@ 15.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 15.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 15.6 + 15.7 +<http://www.example.com/Delay_10_samples> 15.8 + doap:name "10 samples delay" ; 15.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 15.10 + 15.11 +<http://www.example.com/Delay_10_samples/ports/o> lv2:name "Output" . 15.12 + 15.13 +<http://www.example.com/Delay_10_samples/ports/i> lv2:name "Input" .
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/permafrost/examples/Delay_1_sample-extra.ttl Sun May 02 14:19:58 2010 +0300 16.3 @@ -0,0 +1,10 @@ 16.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 16.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 16.6 + 16.7 +<http://www.example.com/Delay_1_sample> 16.8 + doap:name "1 sample delay" ; 16.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 16.10 + 16.11 +<http://www.example.com/Delay_1_sample/ports/o> lv2:name "Output" . 16.12 + 16.13 +<http://www.example.com/Delay_1_sample/ports/i> lv2:name "Input" .
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/permafrost/examples/Delay_1_sec-extra.ttl Sun May 02 14:19:58 2010 +0300 17.3 @@ -0,0 +1,10 @@ 17.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 17.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 17.6 + 17.7 +<http://www.example.com/Delay_1_sec> 17.8 + doap:name "1 second delay" ; 17.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 17.10 + 17.11 +<http://www.example.com/Delay_1_sec/ports/o> lv2:name "Output" . 17.12 + 17.13 +<http://www.example.com/Delay_1_sec/ports/i> lv2:name "Input" .
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/permafrost/examples/Delay_max_10_secs-extra.ttl Sun May 02 14:19:58 2010 +0300 18.3 @@ -0,0 +1,15 @@ 18.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 18.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 18.6 + 18.7 +<http://www.example.com/Delay_max_10_secs> 18.8 + doap:name "Max 10 secs delay" ; 18.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 18.10 + 18.11 +<http://www.example.com/Delay_max_10_secs/ports/o> lv2:name "Output" . 18.12 + 18.13 +<http://www.example.com/Delay_max_10_secs/ports/seconds> lv2:name "Seconds" ; 18.14 + lv2:minimum 0 ; 18.15 + lv2:maximum 10 ; 18.16 + lv2:default 1 . 18.17 + 18.18 +<http://www.example.com/Delay_max_10_secs/ports/i> lv2:name "Input" .
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/permafrost/examples/First_order_FIR-extra.ttl Sun May 02 14:19:58 2010 +0300 19.3 @@ -0,0 +1,20 @@ 19.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 19.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 19.6 + 19.7 +<http://www.example.com/First_order_FIR> 19.8 + doap:name "First order FIR filter" ; 19.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 19.10 + 19.11 +<http://www.example.com/First_order_FIR/ports/o> lv2:name "Output" . 19.12 + 19.13 +<http://www.example.com/First_order_FIR/ports/h1> lv2:name "h1" ; 19.14 + lv2:minimum -10 ; 19.15 + lv2:maximum 10 ; 19.16 + lv2:default 1 . 19.17 + 19.18 +<http://www.example.com/First_order_FIR/ports/h2> lv2:name "h2" ; 19.19 + lv2:minimum -10 ; 19.20 + lv2:maximum 10 ; 19.21 + lv2:default 0 . 19.22 + 19.23 +<http://www.example.com/First_order_FIR/ports/i> lv2:name "Input" .
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/permafrost/examples/Inverse_comb_filter_max_10_secs-extra.ttl Sun May 02 14:19:58 2010 +0300 20.3 @@ -0,0 +1,20 @@ 20.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 20.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 20.6 + 20.7 +<http://www.example.com/Inverse_comb_filter_max_10_secs> 20.8 + doap:name "Inverse comb filter (max 10 secs)" ; 20.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 20.10 + 20.11 +<http://www.example.com/Inverse_comb_filter_max_10_secs/ports/o> lv2:name "Output" . 20.12 + 20.13 +<http://www.example.com/Inverse_comb_filter_max_10_secs/ports/delay> lv2:name "Delay" ; 20.14 + lv2:minimum 0 ; 20.15 + lv2:maximum 10 ; 20.16 + lv2:default 1 . 20.17 + 20.18 +<http://www.example.com/Inverse_comb_filter_max_10_secs/ports/feedforward> lv2:name "Feedforward" ; 20.19 + lv2:minimum -1 ; 20.20 + lv2:maximum 1 ; 20.21 + lv2:default 0.1 . 20.22 + 20.23 +<http://www.example.com/Inverse_comb_filter_max_10_secs/ports/i> lv2:name "Input" .
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/permafrost/examples/One_pole_filter-extra.ttl Sun May 02 14:19:58 2010 +0300 21.3 @@ -0,0 +1,15 @@ 21.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 21.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 21.6 + 21.7 +<http://www.example.com/One_pole_filter> 21.8 + doap:name "One pole filter" ; 21.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 21.10 + 21.11 +<http://www.example.com/One_pole_filter/ports/o> lv2:name "Output" . 21.12 + 21.13 +<http://www.example.com/One_pole_filter/ports/a1> lv2:name "a1" ; 21.14 + lv2:minimum -1 ; 21.15 + lv2:maximum 1 ; 21.16 + lv2:default 0 . 21.17 + 21.18 +<http://www.example.com/One_pole_filter/ports/i> lv2:name "Input" .
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/permafrost/examples/Oscillator-extra.ttl Sun May 02 14:19:58 2010 +0300 22.3 @@ -0,0 +1,24 @@ 22.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 22.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 22.6 + 22.7 +<http://www.example.com/Oscillator> 22.8 + doap:name "Oscillator" ; 22.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 22.10 + 22.11 +<http://www.example.com/Oscillator/ports/o> lv2:name "Output" . 22.12 + 22.13 +<http://www.example.com/Oscillator/ports/frequency> lv2:name "Frequency" ; 22.14 + lv2:minimum 0 ; 22.15 + lv2:maximum 0.5 ; 22.16 + lv2:default 0.1 ; 22.17 + lv2:portProperty lv2:sampleRate . 22.18 + 22.19 +<http://www.example.com/Oscillator/ports/amplitude> lv2:name "Amplitude" ; 22.20 + lv2:minimum 0 ; 22.21 + lv2:maximum 2 ; 22.22 + lv2:default 1 . 22.23 + 22.24 +<http://www.example.com/Oscillator/ports/offset> lv2:name "Offset" ; 22.25 + lv2:minimum -1 ; 22.26 + lv2:maximum 1 ; 22.27 + lv2:default 0 .
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/permafrost/examples/RC_double_lowpass-extra.ttl Sun May 02 14:19:58 2010 +0300 23.3 @@ -0,0 +1,16 @@ 23.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 23.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 23.6 + 23.7 +<http://www.example.com/RC_double_lowpass> 23.8 + doap:name "RC double lowpass filter simulator" ; 23.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 23.10 + 23.11 +<http://www.example.com/RC_double_lowpass/ports/Vout> lv2:name "Vout" . 23.12 + 23.13 +<http://www.example.com/RC_double_lowpass/ports/cut_frequency> lv2:name "Cut frequency" ; 23.14 + lv2:minimum 0 ; 23.15 + lv2:maximum 0.5 ; 23.16 + lv2:default 0.1 ; 23.17 + lv2:portProperty lv2:sampleRate . 23.18 + 23.19 +<http://www.example.com/RC_double_lowpass/ports/Vin> lv2:name "Vin" .
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/permafrost/examples/RC_lowpass-extra.ttl Sun May 02 14:19:58 2010 +0300 24.3 @@ -0,0 +1,16 @@ 24.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 24.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 24.6 + 24.7 +<http://www.example.com/RC_lowpass> 24.8 + doap:name "RC_lowpass" ; 24.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 24.10 + 24.11 +<http://www.example.com/RC_lowpass/ports/Vout> lv2:name "Vout" . 24.12 + 24.13 +<http://www.example.com/RC_lowpass/ports/cut_frequency> lv2:name "Cut frequency" ; 24.14 + lv2:minimum 0 ; 24.15 + lv2:maximum 0.5 ; 24.16 + lv2:default 0.1 ; 24.17 + lv2:portProperty lv2:sampleRate . 24.18 + 24.19 +<http://www.example.com/RC_lowpass/ports/Vin> lv2:name "Vin" .
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/permafrost/examples/Sawtooth-extra.ttl Sun May 02 14:19:58 2010 +0300 25.3 @@ -0,0 +1,23 @@ 25.4 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . 25.5 +@prefix doap: <http://usefulinc.com/ns/doap#> . 25.6 + 25.7 +<http://www.example.com/Sawtooth> 25.8 + doap:name "Sawtooth generator" ; 25.9 + doap:license <http://usefulinc.com/doap/licenses/bsd> . 25.10 + 25.11 +<http://www.example.com/Sawtooth/ports/o> lv2:name "Output" . 25.12 + 25.13 +<http://www.example.com/Sawtooth/ports/frequency> lv2:name "Frequency" ; 25.14 + lv2:minimum 0 ; 25.15 + lv2:maximum 0.5 ; 25.16 + lv2:default 0.1 . 25.17 + 25.18 +<http://www.example.com/Sawtooth/ports/amplitude> lv2:name "Amplitude" ; 25.19 + lv2:minimum 0 ; 25.20 + lv2:maximum 2 ; 25.21 + lv2:default 1 . 25.22 + 25.23 +<http://www.example.com/Sawtooth/ports/offset> lv2:name "Offset" ; 25.24 + lv2:minimum -1 ; 25.25 + lv2:maximum 1 ; 25.26 + lv2:default 0 .
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/permafrost/examples/amp.pmf Sun May 02 14:19:58 2010 +0300 26.3 @@ -0,0 +1,44 @@ 26.4 +# Permafrost - Physical modelling framework 26.5 +# 26.6 +# Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 26.7 +# 26.8 +# See the COPYING file for license conditions. 26.9 + 26.10 +import common; 26.11 +import m; 26.12 + 26.13 +block dB_to_lin 26.14 +{ 26.15 + input i; 26.16 + output o; 26.17 + 26.18 + o = m_pow(10, i / 20); 26.19 +} 26.20 + 26.21 +system Amp 26.22 +{ 26.23 + sync input i; 26.24 + sync output o; 26.25 + async input gain; 26.26 + 26.27 + mul m; 26.28 + 26.29 + o = m.o; 26.30 + m.i1 = i; 26.31 + m.i2 = gain; 26.32 +} 26.33 + 26.34 +system Amp_dB 26.35 +{ 26.36 + sync input i; 26.37 + sync output o; 26.38 + async input gain_dB; 26.39 + 26.40 + mul m; 26.41 + dB_to_lin d; 26.42 + 26.43 + o = m.o; 26.44 + m.i1 = i; 26.45 + m.i2 = d.o; 26.46 + d.i = gain_dB; 26.47 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/permafrost/examples/common.pmf Sun May 02 14:19:58 2010 +0300 27.3 @@ -0,0 +1,49 @@ 27.4 +# Permafrost - Physical modelling framework 27.5 +# 27.6 +# Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 27.7 +# 27.8 +# See the COPYING file for license conditions. 27.9 + 27.10 +block sum 27.11 +{ 27.12 + input i1; 27.13 + input i2; 27.14 + output o; 27.15 + 27.16 + o = i1 + i2; 27.17 +} 27.18 + 27.19 +block mul 27.20 +{ 27.21 + input i1; 27.22 + input i2; 27.23 + output o; 27.24 + 27.25 + o = i1 * i2; 27.26 +} 27.27 + 27.28 +block delay_1_sample 27.29 +{ 27.30 + input i; 27.31 + output o; 27.32 + 27.33 + o = i[1]; 27.34 +} 27.35 + 27.36 +block delay_line 27.37 +{ 27.38 + input i; 27.39 + output o; 27.40 + input delay; 27.41 + input delay_max; 27.42 + 27.43 + o = i[delay, delay_max]; 27.44 +} 27.45 + 27.46 +block secs_to_samples 27.47 +{ 27.48 + input secs; 27.49 + output samples; 27.50 + 27.51 + samples = secs * sample_rate; 27.52 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/permafrost/examples/delay.pmf Sun May 02 14:19:58 2010 +0300 28.3 @@ -0,0 +1,79 @@ 28.4 +# Permafrost - Physical modelling framework 28.5 +# 28.6 +# Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 28.7 +# 28.8 +# See the COPYING file for license conditions. 28.9 + 28.10 +import common; 28.11 + 28.12 +system Delay_1_sample 28.13 +{ 28.14 + sync input i; 28.15 + sync output o; 28.16 + 28.17 + delay_line d; 28.18 + 28.19 + o = d.o; 28.20 + d.i = i; 28.21 + d.delay = 1; 28.22 + d.delay_max = 1; 28.23 +} 28.24 + 28.25 +system Delay_10_samples 28.26 +{ 28.27 + sync input i; 28.28 + sync output o; 28.29 + 28.30 + delay_line d; 28.31 + 28.32 + o = d.o; 28.33 + d.i = i; 28.34 + d.delay = 10; 28.35 + d.delay_max = 10; 28.36 +} 28.37 + 28.38 +system Delay_10000_samples 28.39 +{ 28.40 + sync input i; 28.41 + sync output o; 28.42 + 28.43 + delay_line d; 28.44 + 28.45 + o = d.o; 28.46 + d.i = i; 28.47 + d.delay = 10000; 28.48 + d.delay_max = 10000; 28.49 +} 28.50 + 28.51 +system Delay_1_sec 28.52 +{ 28.53 + sync input i; 28.54 + sync output o; 28.55 + 28.56 + delay_line d; 28.57 + secs_to_samples s; 28.58 + 28.59 + o = d.o; 28.60 + d.i = i; 28.61 + d.delay = s.samples; 28.62 + d.delay_max = s.samples; 28.63 + s.secs = 1; 28.64 +} 28.65 + 28.66 +system Delay_max_10_secs 28.67 +{ 28.68 + sync input i; 28.69 + sync output o; 28.70 + async input seconds; 28.71 + 28.72 + delay_line d; 28.73 + secs_to_samples s; 28.74 + secs_to_samples s_max; 28.75 + 28.76 + o = d.o; 28.77 + d.i = i; 28.78 + d.delay = s.samples; 28.79 + d.delay_max = s_max.samples; 28.80 + s.secs = seconds; 28.81 + s_max.secs = 10; 28.82 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/permafrost/examples/filters.pmf Sun May 02 14:19:58 2010 +0300 29.3 @@ -0,0 +1,115 @@ 29.4 +# Permafrost - Physical modelling framework 29.5 +# 29.6 +# Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 29.7 +# 29.8 +# See the COPYING file for license conditions. 29.9 + 29.10 +import common; 29.11 + 29.12 +block first_order_FIR 29.13 +{ 29.14 + input i; 29.15 + output o; 29.16 + input h1; 29.17 + input h2; 29.18 + 29.19 + o = h1 * i + h2 * i[1]; 29.20 +} 29.21 + 29.22 +system First_order_FIR 29.23 +{ 29.24 + sync input i; 29.25 + sync output o; 29.26 + async input h1; 29.27 + async input h2; 29.28 + 29.29 + first_order_FIR f; 29.30 + 29.31 + o = f.o; 29.32 + f.i = i; 29.33 + f.h1 = h1; 29.34 + f.h2 = h2; 29.35 +} 29.36 + 29.37 +block one_pole 29.38 +{ 29.39 + input i; 29.40 + input prev; 29.41 + input a1; 29.42 + output o; 29.43 + 29.44 + o = i + a1 * prev; 29.45 +} 29.46 + 29.47 +system One_pole_filter 29.48 +{ 29.49 + sync input i; 29.50 + sync output o; 29.51 + async input a1; 29.52 + 29.53 + one_pole op; 29.54 + delay_1_sample d; 29.55 + 29.56 + o = op.o; 29.57 + op.i = i; 29.58 + d.i = op.o; 29.59 + op.prev = d.o; 29.60 + op.a1 = a1; 29.61 +} 29.62 + 29.63 +system Comb_filter_max_10_secs 29.64 +{ 29.65 + sync input i; 29.66 + sync output o; 29.67 + async input feedback; 29.68 + async input delay; 29.69 + 29.70 + one_pole op; 29.71 + delay_line d; 29.72 + secs_to_samples s; 29.73 + secs_to_samples s_max; 29.74 + 29.75 + o = op.o; 29.76 + op.i = i; 29.77 + d.i = op.o; 29.78 + op.prev = d.o; 29.79 + op.a1 = feedback; 29.80 + s.secs = delay; 29.81 + d.delay = s.samples; 29.82 + d.delay_max = s_max.samples; 29.83 + s_max.secs = 10; 29.84 +} 29.85 + 29.86 +block sub 29.87 +{ 29.88 + input i1; 29.89 + input i2; 29.90 + output o; 29.91 + 29.92 + o = i1 - i2; 29.93 +} 29.94 + 29.95 +system Inverse_comb_filter_max_10_secs 29.96 +{ 29.97 + sync input i; 29.98 + sync output o; 29.99 + async input feedforward; 29.100 + async input delay; 29.101 + 29.102 + sub s; 29.103 + mul m; 29.104 + delay_line d; 29.105 + secs_to_samples ss; 29.106 + secs_to_samples ss_max; 29.107 + 29.108 + o = s.o; 29.109 + s.i1 = i; 29.110 + s.i2 = m.o; 29.111 + m.i1 = d.o; 29.112 + m.i2 = feedforward; 29.113 + d.i = i; 29.114 + d.delay = ss.samples; 29.115 + ss.secs = delay; 29.116 + d.delay_max = ss_max.samples; 29.117 + ss_max.secs = 10; 29.118 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/permafrost/examples/funcgen.pmf Sun May 02 14:19:58 2010 +0300 30.3 @@ -0,0 +1,98 @@ 30.4 +# Permafrost - Physical modelling framework 30.5 +# 30.6 +# Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 30.7 +# 30.8 +# See the COPYING file for license conditions. 30.9 + 30.10 +import m; 30.11 +import common; 30.12 + 30.13 +block step 30.14 +{ 30.15 + input prev; 30.16 + input step; 30.17 + output o; 30.18 + 30.19 + o = m_fmod(prev + step, 1); 30.20 +} 30.21 + 30.22 +macro sawtooth 30.23 +{ 30.24 + output o; 30.25 + input frequency; # ratio between frequency and sample rate 30.26 + 30.27 + step s; 30.28 + delay_1_sample d; 30.29 + 30.30 + o = s.o; 30.31 + d.i = s.o; 30.32 + s.prev = d.o; 30.33 + s.step = frequency; 30.34 +} 30.35 + 30.36 +macro center_gain_offset 30.37 +{ 30.38 + input i; 30.39 + input center; 30.40 + input gain; 30.41 + input offset; 30.42 + output o; 30.43 + 30.44 + sum off_c; 30.45 + mul m; 30.46 + sum off_o; 30.47 + 30.48 + off_c.i1 = i; 30.49 + off_c.i2 = center; 30.50 + m.i1 = off_c.o; 30.51 + m.i2 = gain; 30.52 + off_o.i1 = m.o; 30.53 + off_o.i2 = offset; 30.54 + o = off_o.o; 30.55 +} 30.56 + 30.57 +system Sawtooth 30.58 +{ 30.59 + sync output o; 30.60 + async input frequency; 30.61 + async input offset; 30.62 + async input amplitude; 30.63 + 30.64 + sawtooth saw; 30.65 + center_gain_offset cgo; 30.66 + 30.67 + o = cgo.o; 30.68 + saw.frequency = frequency; 30.69 + cgo.i = saw.o; 30.70 + cgo.center = -0.5; 30.71 + cgo.gain = amplitude; 30.72 + cgo.offset = offset; 30.73 +} 30.74 + 30.75 +block sin 30.76 +{ 30.77 + input i; 30.78 + output o; 30.79 + 30.80 + o = m_sin(2 * m_pi * i); 30.81 +} 30.82 + 30.83 +system Oscillator 30.84 +{ 30.85 + sync output o; 30.86 + async input frequency; 30.87 + async input offset; 30.88 + async input amplitude; 30.89 + 30.90 + sawtooth saw; 30.91 + sin s; 30.92 + center_gain_offset cgo; 30.93 + 30.94 + o = cgo.o; 30.95 + saw.frequency = frequency; 30.96 + s.i = saw.o; 30.97 + cgo.i = s.o; 30.98 + cgo.center = 0; 30.99 + cgo.gain = amplitude; 30.100 + cgo.offset = offset; 30.101 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/permafrost/examples/rc_lowpass.pmf Sun May 02 14:19:58 2010 +0300 31.3 @@ -0,0 +1,97 @@ 31.4 +# Permafrost - Physical modelling framework 31.5 +# 31.6 +# Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 31.7 +# 31.8 +# See the COPYING file for license conditions. 31.9 + 31.10 +import wdf; 31.11 +import m; 31.12 + 31.13 +macro RC_lowpass 31.14 +{ 31.15 + input R; 31.16 + input C; 31.17 + output V; 31.18 + w_port R_side; 31.19 + w_port C_side; 31.20 + input R_side_Z; 31.21 + output C_side_Z; 31.22 + 31.23 + wdf_ideal_resistor resistor; 31.24 + wdf_ideal_capacitor capacitor; 31.25 + wdf_junc_3port_series s; 31.26 + wdf_junc_3port_parallel p; 31.27 + 31.28 + resistor.R = R; 31.29 + capacitor.C = C; 31.30 + V = capacitor.V; 31.31 + s.w1 = resistor.w; 31.32 + s.Z1 = resistor.Z; 31.33 + s.w2 = R_side; 31.34 + s.Z2 = R_side_Z; 31.35 + p.w1 = s.wup; 31.36 + p.Z1 = s.Zup; 31.37 + p.w2 = capacitor.w; 31.38 + p.Z2 = capacitor.Z; 31.39 + C_side = p.wup; 31.40 + C_side_Z = p.Zup; 31.41 +} 31.42 + 31.43 +block freq_to_RC 31.44 +{ 31.45 + input freq; # fraction of sample rate 31.46 + output R; 31.47 + output C; 31.48 + 31.49 + R = 1; 31.50 + C = 1 / (2 * m_pi * (2 * sample_rate * m_atan(2 * freq))); 31.51 +} 31.52 + 31.53 +system RC_lowpass 31.54 +{ 31.55 + sync input Vin; 31.56 + sync output Vout; 31.57 + async input cut_frequency; 31.58 + 31.59 + freq_to_RC fc; 31.60 + RC_lowpass lp; 31.61 + wdf_voltage_source Vs; 31.62 + wdf_open_circuit oc; 31.63 + 31.64 + Vs.V = Vin; 31.65 + Vs.R = 0; 31.66 + fc.freq = cut_frequency; 31.67 + lp.R = fc.R; 31.68 + lp.C = fc.C; 31.69 + lp.R_side = Vs.w; 31.70 + lp.R_side_Z = Vs.Z; 31.71 + lp.C_side = oc.w; 31.72 + Vout = lp.V; 31.73 +} 31.74 + 31.75 +system RC_double_lowpass 31.76 +{ 31.77 + sync input Vin; 31.78 + sync output Vout; 31.79 + async input cut_frequency; 31.80 + 31.81 + freq_to_RC fc; 31.82 + RC_lowpass lp1; 31.83 + RC_lowpass lp2; 31.84 + wdf_voltage_source Vs; 31.85 + wdf_open_circuit oc; 31.86 + 31.87 + Vs.V = Vin; 31.88 + Vs.R = 0; 31.89 + fc.freq = cut_frequency; 31.90 + lp1.R = fc.R; 31.91 + lp1.C = fc.C; 31.92 + lp1.R_side = Vs.w; 31.93 + lp1.R_side_Z = Vs.Z; 31.94 + lp2.R = fc.R; 31.95 + lp2.C = fc.C; 31.96 + lp2.R_side = lp1.C_side; 31.97 + lp2.R_side_Z = lp1.C_side_Z; 31.98 + lp2.C_side = oc.w; 31.99 + Vout = lp2.V; 31.100 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/permafrost/examples/waveshaper.pmf Sun May 02 14:19:58 2010 +0300 32.3 @@ -0,0 +1,29 @@ 32.4 +# Permafrost - Physical modelling framework 32.5 +# 32.6 +# Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 32.7 +# 32.8 +# See the COPYING file for license conditions. 32.9 + 32.10 +import m; 32.11 + 32.12 +block waveshaper 32.13 +{ 32.14 + input i; 32.15 + input level; 32.16 + output o; 32.17 + 32.18 + o = m_atan(i * level) / m_atan(level); 32.19 +} 32.20 + 32.21 +system Arctan_waveshaper 32.22 +{ 32.23 + sync input i; 32.24 + async input level; 32.25 + sync output o; 32.26 + 32.27 + waveshaper w; 32.28 + 32.29 + o = w.o; 32.30 + w.i = i; 32.31 + w.level = level; 32.32 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/permafrost/examples/wdf.pmf Sun May 02 14:19:58 2010 +0300 33.3 @@ -0,0 +1,117 @@ 33.4 +# Permafrost - Physical modelling framework 33.5 +# 33.6 +# Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 33.7 +# 33.8 +# See the COPYING file for license conditions. 33.9 + 33.10 +block wdf_junc_3port_series 33.11 +{ 33.12 + w_port w1; 33.13 + w_port w2; 33.14 + w_port wup; 33.15 + input Z1; 33.16 + input Z2; 33.17 + output Zup; 33.18 + #input Iext; 33.19 + #output V; 33.20 + 33.21 + Zup = Z1 + Z2; 33.22 + wup.out = -(w1.in + w2.in); 33.23 + w1.out = w1.in - ((wup.in + w1.in + w2.in) * Z1) / (Z1 + Z2); 33.24 + w2.out = w2.in - ((wup.in + w1.in + w2.in) * Z2) / (Z1 + Z2); 33.25 +} 33.26 + 33.27 +block wdf_junc_3port_parallel 33.28 +{ 33.29 + w_port w1; 33.30 + w_port w2; 33.31 + w_port wup; 33.32 + input Z1; 33.33 + input Z2; 33.34 + output Zup; 33.35 + #input Iext; 33.36 + #output V; 33.37 + 33.38 + Zup = (Z1 * Z2) / (Z1 + Z2); 33.39 + wup.out = (Z2 * w1.in + Z1 * w2.in) / (Z1 + Z2); 33.40 + w1.out = (Z2 * w1.in + Z1 * w2.in) / (Z1 + Z2) + wup.in - w1.in; 33.41 + w2.out = (Z2 * w1.in + Z1 * w2.in) / (Z1 + Z2) + wup.in - w2.in; 33.42 +} 33.43 + 33.44 +block wdf_voltage_source 33.45 +{ 33.46 + w_port w; 33.47 + input V; 33.48 + input R; 33.49 + output Z; 33.50 + 33.51 + w.out = V; 33.52 + Z = R; 33.53 +} 33.54 + 33.55 +block wdf_current_source 33.56 +{ 33.57 + w_port w; 33.58 + input I; 33.59 + input R; 33.60 + output Z; 33.61 + 33.62 + w.out = R * I; 33.63 + Z = R; 33.64 +} 33.65 + 33.66 +block wdf_ideal_resistor 33.67 +{ 33.68 + w_port w; 33.69 + input R; 33.70 + output V; 33.71 + output I; 33.72 + output Z; 33.73 + 33.74 + w.out = 0; 33.75 + V = w.in / 2; 33.76 + I = w.in / (2 * R); 33.77 + Z = R; 33.78 +} 33.79 + 33.80 +block wdf_ideal_capacitor 33.81 +{ 33.82 + w_port w; 33.83 + input C; 33.84 + output V; 33.85 + output I; 33.86 + output Z; 33.87 + 33.88 + w.out = w.in[1]; 33.89 + V = (w.in + w.in[1]) / 2; 33.90 + I = (w.in - w.in[1]) / (2 * C * sample_rate); 33.91 + Z = 1 / (2 * C * sample_rate); 33.92 +} 33.93 + 33.94 +block wdf_ideal_inductor 33.95 +{ 33.96 + w_port w; 33.97 + input L; 33.98 + output V; 33.99 + output I; 33.100 + output Z; 33.101 + 33.102 + w.out = -w.in[1]; 33.103 + V = (w.in - w.in[1]) / 2; 33.104 + I = (w.in + w.in[1]) * sample_rate / (2 * L); 33.105 + Z = 2 * L / sample_rate; 33.106 +} 33.107 + 33.108 +block wdf_short_circuit 33.109 +{ 33.110 + w_port w; 33.111 + 33.112 + w.out = -w.in; 33.113 +} 33.114 + 33.115 +block wdf_open_circuit 33.116 +{ 33.117 + w_port w; 33.118 + 33.119 + w.out = w.in; 33.120 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/permafrost/lib/m.pmf Sun May 02 14:19:58 2010 +0300 34.3 @@ -0,0 +1,66 @@ 34.4 +# Permafrost - Physical modelling framework 34.5 +# 34.6 +# Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 34.7 +# 34.8 +# See the COPYING file for license conditions. 34.9 + 34.10 +# Functions 34.11 +ext_function m_acos = acosf, acos, 1, "math.h", "m"; 34.12 +ext_function m_acosh = acoshf, acosh, 1, "math.h", "m"; 34.13 +ext_function m_asin = asinf, asin, 1, "math.h", "m"; 34.14 +ext_function m_asinh = asinhf, asinh, 1, "math.h", "m"; 34.15 +ext_function m_atan = atanf, atan, 1, "math.h", "m"; 34.16 +ext_function m_atan2 = atan2f, atan2, 2, "math.h", "m"; 34.17 +ext_function m_atanh = atanhf, atanh, 1, "math.h", "m"; 34.18 +ext_function m_cbrt = cbrtf, cbrt, 1, "math.h", "m"; 34.19 +ext_function m_ceil = ceilf, ceil, 1, "math.h", "m"; 34.20 +ext_function m_copysign = copysignf, copysign, 2, "math.h", "m"; 34.21 +ext_function m_cos = cosf, cos, 1, "math.h", "m"; 34.22 +ext_function m_cosh = coshf, cosh, 1, "math.h", "m"; 34.23 +ext_function m_erf = erff, erf, 1, "math.h", "m"; 34.24 +ext_function m_erfc = erfcf, erfc, 1, "math.h", "m"; 34.25 +ext_function m_exp = expf, exp, 1, "math.h", "m"; 34.26 +ext_function m_exp2 = exp2f, exp2, 1, "math.h", "m"; 34.27 +ext_function m_expm1 = expm1f, expm1, 1, "math.h", "m"; 34.28 +ext_function m_fabs = fabsf, fabs, 1, "math.h", "m"; 34.29 +ext_function m_fdim = fdimf, fdim, 2, "math.h", "m"; 34.30 +ext_function m_floor = floorf, floor, 1, "math.h", "m"; 34.31 +ext_function m_fma = fmaf, fma, 3, "math.h", "m"; 34.32 +ext_function m_fmax = fmaxf, fmax, 2, "math.h", "m"; 34.33 +ext_function m_fmin = fminf, fmin, 2, "math.h", "m"; 34.34 +ext_function m_fmod = fmodf, fmod, 2, "math.h", "m"; 34.35 +ext_function m_hypot = hypotf, hypot, 2, "math.h", "m"; 34.36 +ext_function m_lgamma = lgammaf, lgamma, 1, "math.h", "m"; 34.37 +ext_function m_log = logf, log, 1, "math.h", "m"; 34.38 +ext_function m_log10 = log10f, log10, 1, "math.h", "m"; 34.39 +ext_function m_log1p = log1pf, log1p, 1, "math.h", "m"; 34.40 +ext_function m_log2 = log2f, log2, 1, "math.h", "m"; 34.41 +ext_function m_logb = logbf, logb, 1, "math.h", "m"; 34.42 +ext_function m_nearbyint = nearbyintf, nearbyint, 1, "math.h", "m"; 34.43 +ext_function m_nextafter = nextafeterf, nextafter, 2, "math.h", "m"; 34.44 +ext_function m_pow = powf, pow, 2, "math.h", "m"; 34.45 +ext_function m_remainder = remainderf, remainder, 2, "math.h", "m"; 34.46 +ext_function m_rint = rintf, rint, 1, "math.h", "m"; 34.47 +ext_function m_round = roundf, round, 1, "math.h", "m"; 34.48 +ext_function m_sin = sinf, sin, 1, "math.h", "m"; 34.49 +ext_function m_sinh = sinhf, sinh, 1, "math.h", "m"; 34.50 +ext_function m_sqrt = sqrtf, sqrt, 1, "math.h", "m"; 34.51 +ext_function m_tan = tanf, tan, 1, "math.h", "m"; 34.52 +ext_function m_tanh = tanhf, tanh, 1, "math.h", "m"; 34.53 +ext_function m_tgamma = tgammaf, tgamma, 1, "math.h", "m"; 34.54 +ext_function m_trunc = truncf, trunc, 1, "math.h", "m"; 34.55 + 34.56 +# Useful constants 34.57 +const m_e = 2.7182818284590452354; # e 34.58 +const m_log2e = 1.4426950408889634074; # log2(e) 34.59 +const m_log10e = 0.43429448190325182765; # log10(e) 34.60 +const m_ln2 = 0.69314718055994530942; # ln(2) 34.61 +const m_ln10 = 2.30258509299404568402; # ln(10) 34.62 +const m_pi = 3.14159265358979323846; # pi 34.63 +const m_pi_2 = 1.57079632679489661923; # pi / 2 34.64 +const m_pi_4 = 0.78539816339744830962; # pi / 4 34.65 +const m_1_pi = 0.31830988618379067154; # 1 / pi 34.66 +const m_2_pi = 0.63661977236758134308; # 2 / pi 34.67 +const m_2_sqrtpi = 1.12837916709551257390; # 2 / sqrt(pi) 34.68 +const m_sqrt2 = 1.41421356237309504880; # sqrt(2) 34.69 +const m_sqrt1_2 = 0.70710678118654752440; # 1 / sqrt(2)
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/permafrost/src/compile.c Sun May 02 14:19:58 2010 +0300 35.3 @@ -0,0 +1,1098 @@ 35.4 +/* 35.5 + * Permafrost - Physical modelling framework 35.6 + * 35.7 + * Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 35.8 + * 35.9 + * See the COPYING file for license conditions. 35.10 + */ 35.11 + 35.12 +#include <stdlib.h> 35.13 +#include <stdio.h> 35.14 +#include <string.h> 35.15 +#include <errno.h> 35.16 +#include <float.h> 35.17 + 35.18 +#include "src/types.h" 35.19 +#include "src/util.h" 35.20 +#include "src/list.h" 35.21 +#include "src/expr.h" 35.22 +#include "src/compile.h" 35.23 + 35.24 +char *compile_output_dir = NULL; 35.25 +char compile_gen_code = 1; 35.26 +char compile_gen_descriptor = 1; 35.27 +char compile_gen_makefile = 1; 35.28 +char compile_gen_manifest = 1; 35.29 +char compile_gen_plugin_ttl = 1; 35.30 +char compile_gen_extra_ttl = 1; 35.31 +char *compile_uri_prefix = "http://www.example.com/"; 35.32 +char *compile_license_uri = "http://usefulinc.com/doap/licenses/unknown"; 35.33 + 35.34 +static const char * 35.35 +get_filename(const char *filename, const char *suffix) 35.36 +{ 35.37 + char *buf; 35.38 + 35.39 + if ((compile_output_dir == NULL) && (suffix == NULL)) 35.40 + return filename; 35.41 + 35.42 + if ((compile_output_dir != NULL) && (suffix != NULL)) 35.43 + { 35.44 + buf = xmalloc(strlen(compile_output_dir) + strlen(filename) 35.45 + + strlen(suffix) + 2); 35.46 + sprintf(buf, "%s/%s%s", compile_output_dir, filename, suffix); 35.47 + } 35.48 + else if ((compile_output_dir != NULL) && (suffix == NULL)) 35.49 + { 35.50 + buf = xmalloc(strlen(compile_output_dir) + strlen(filename) 35.51 + + 2); 35.52 + sprintf(buf, "%s/%s", compile_output_dir, filename); 35.53 + } 35.54 + else /* ((compile_output_dir == NULL) && (suffix != NULL)) */ 35.55 + { 35.56 + buf = xmalloc(strlen(filename) + strlen(suffix) + 1); 35.57 + sprintf(buf, "%s%s", filename, suffix); 35.58 + } 35.59 + 35.60 + return buf; 35.61 +} 35.62 + 35.63 +/* FIXME: possibility of false positives (file exists, but couldn't open) */ 35.64 +static char 35.65 +file_exists(const char *filename, const char *suffix) 35.66 +{ 35.67 + FILE *fp; 35.68 + const char *f; 35.69 + 35.70 + f = get_filename(filename, suffix); 35.71 + 35.72 + fp = fopen(f, "r"); 35.73 + if (fp != NULL) 35.74 + fclose(fp); 35.75 + 35.76 + if (f != filename) 35.77 + free((void *)f); 35.78 + 35.79 + return fp != NULL; 35.80 +} 35.81 + 35.82 +static FILE * 35.83 +xfopenw(const char *filename, const char *suffix) 35.84 +{ 35.85 + FILE *fp; 35.86 + const char *f; 35.87 + 35.88 + f = get_filename(filename, suffix); 35.89 + 35.90 + fp = fopen(f, "w"); 35.91 + if (fp == NULL) 35.92 + { 35.93 + fprintf(stderr, "error: could not create file `%s': %s\n", f, 35.94 + strerror(errno)); 35.95 + exit(EXIT_FAILURE); 35.96 + } 35.97 + 35.98 + if (f != filename) 35.99 + free((void *)f); 35.100 + 35.101 + return fp; 35.102 +} 35.103 + 35.104 +static void 35.105 +manifest_print_plugin(void *data, void *context) 35.106 +{ 35.107 + struct scheduled_system *ss; 35.108 + FILE *fp; 35.109 + 35.110 + ss = (struct scheduled_system *)data; 35.111 + fp = (FILE *)context; 35.112 + 35.113 + fprintf(fp, "\n"); 35.114 + fprintf(fp, "<%s%s> a lv2:Plugin ;\n", compile_uri_prefix, 35.115 + ss->system->id); 35.116 + fprintf(fp, "\tlv2:binary <plugin.so> ;\n"); 35.117 + fprintf(fp, "\trdfs:seeAlso <%s.ttl> ", ss->system->id); 35.118 + fprintf(fp, ";\n\trdfs:seeAlso <%s-extra.ttl> ", ss->system->id); 35.119 + fprintf(fp, ".\n"); 35.120 +} 35.121 + 35.122 +struct ttl_print_io_port_context 35.123 + { 35.124 + struct scheduled_system *ss; 35.125 + FILE *fp; 35.126 + }; 35.127 + 35.128 +static void 35.129 +ttl_print_io_port_uri(void *data, void *context) 35.130 +{ 35.131 + struct scheduled_expr *sexpr; 35.132 + struct ttl_print_io_port_context *ctx; 35.133 + 35.134 + sexpr = (struct scheduled_expr *)data; 35.135 + ctx = (struct ttl_print_io_port_context *)context; 35.136 + 35.137 + if (sexpr->component != NULL) 35.138 + return; 35.139 + 35.140 + fprintf(ctx->fp, ";\n\tlv2:port <%s%s/ports/%s> ", compile_uri_prefix, 35.141 + ctx->ss->system->id, sexpr->port->id); 35.142 +} 35.143 + 35.144 +static void 35.145 +ttl_print_io_port(void *data, void *context) 35.146 +{ 35.147 + struct scheduled_expr *sexpr; 35.148 + struct ttl_print_io_port_context *ctx; 35.149 + 35.150 + sexpr = (struct scheduled_expr *)data; 35.151 + ctx = (struct ttl_print_io_port_context *)context; 35.152 + 35.153 + if (sexpr->component != NULL) 35.154 + return; 35.155 + 35.156 + fprintf(ctx->fp, "\n"); 35.157 + fprintf(ctx->fp, "<%s%s/ports/%s> a lv2:Port ;\n", compile_uri_prefix, 35.158 + ctx->ss->system->id, sexpr->port->id); 35.159 + fprintf(ctx->fp, "\ta lv2:%s ;\n", 35.160 + (sexpr->port->sync == port_sync_sync) 35.161 + ? "AudioPort" : "ControlPort"); 35.162 + fprintf(ctx->fp, "\ta lv2:%s ;\n", 35.163 + sexpr->is_output ? "OutputPort" : "InputPort"); 35.164 + fprintf(ctx->fp, "\tlv2:index %lu ;\n", sexpr->index); 35.165 + fprintf(ctx->fp, "\tlv2:symbol \"%s\" .\n", sexpr->port->id); 35.166 +} 35.167 + 35.168 +static void 35.169 +ttl_compile(void *data, void *context) 35.170 +{ 35.171 + struct scheduled_system *ss; 35.172 + struct ttl_print_io_port_context t_ctx; 35.173 + FILE *fp; 35.174 + 35.175 + ss = (struct scheduled_system *)data; 35.176 + 35.177 + fp = xfopenw(ss->system->id, ".ttl"); 35.178 + 35.179 + fprintf(fp, "@prefix lv2: <http://lv2plug.in/ns/lv2core#> .\n"); 35.180 + fprintf(fp, "\n"); 35.181 + fprintf(fp, "<%s%s> a lv2:Plugin ", compile_uri_prefix, 35.182 + ss->system->id); 35.183 + 35.184 + t_ctx.ss = ss; 35.185 + t_ctx.fp = fp; 35.186 + list_for_each_rev(ss->exprs, ttl_print_io_port_uri, &t_ctx); 35.187 + 35.188 + fprintf(fp, ".\n"); 35.189 + 35.190 + list_for_each_rev(ss->exprs, ttl_print_io_port, &t_ctx); 35.191 + 35.192 + fclose(fp); 35.193 +} 35.194 + 35.195 +static void 35.196 +ttl_extra_print_io_port(void *data, void *context) 35.197 +{ 35.198 + struct scheduled_expr *sexpr; 35.199 + struct ttl_print_io_port_context *ctx; 35.200 + 35.201 + sexpr = (struct scheduled_expr *)data; 35.202 + ctx = (struct ttl_print_io_port_context *)context; 35.203 + 35.204 + if (sexpr->component != NULL) 35.205 + return; 35.206 + 35.207 + fprintf(ctx->fp, "\n"); 35.208 + fprintf(ctx->fp, "<%s%s/ports/%s> lv2:name \"%s\" .\n", 35.209 + compile_uri_prefix, ctx->ss->system->id, sexpr->port->id, 35.210 + sexpr->port->id); 35.211 +} 35.212 + 35.213 +static void 35.214 +ttl_extra_compile(void *data, void *context) 35.215 +{ 35.216 + struct scheduled_system *ss; 35.217 + struct ttl_print_io_port_context t_ctx; 35.218 + FILE *fp; 35.219 + 35.220 + ss = (struct scheduled_system *)data; 35.221 + 35.222 + if (file_exists(ss->system->id, "-extra.ttl")) 35.223 + return; 35.224 + 35.225 + fp = xfopenw(ss->system->id, "-extra.ttl"); 35.226 + 35.227 + fprintf(fp, "@prefix lv2: <http://lv2plug.in/ns/lv2core#> .\n"); 35.228 + fprintf(fp, "@prefix doap: <http://usefulinc.com/ns/doap#> .\n"); 35.229 + fprintf(fp, "\n"); 35.230 + fprintf(fp, "<%s%s>\n", compile_uri_prefix, ss->system->id); 35.231 + fprintf(fp, "\tdoap:name \"%s\" ;\n", ss->system->id); 35.232 + fprintf(fp, "\tdoap:license <%s> .", compile_license_uri); 35.233 + fprintf(fp, "\n"); 35.234 + 35.235 + t_ctx.ss = ss; 35.236 + t_ctx.fp = fp; 35.237 + list_for_each_rev(ss->exprs, ttl_extra_print_io_port, &t_ctx); 35.238 + 35.239 + fclose(fp); 35.240 +} 35.241 + 35.242 +static void 35.243 +c_print_include(void *data, void *context) 35.244 +{ 35.245 + struct scheduled_system *ss; 35.246 + FILE *fp; 35.247 + 35.248 + ss = (struct scheduled_system *)data; 35.249 + fp = (FILE *)context; 35.250 + 35.251 + fprintf(fp, "#include \"%s.h\"\n", ss->system->id); 35.252 +} 35.253 + 35.254 +static void 35.255 +c_print_descriptor(void *data, void *context) 35.256 +{ 35.257 + struct scheduled_system *ss; 35.258 + FILE *fp; 35.259 + 35.260 + ss = (struct scheduled_system *)data; 35.261 + fp = (FILE *)context; 35.262 + 35.263 + fprintf(fp, "\n"); 35.264 + fprintf(fp, "static const LV2_Descriptor descriptor_%s =\n", 35.265 + ss->system->id); 35.266 + fprintf(fp, " {\n"); 35.267 + fprintf(fp, "\t/* .URI\t\t\t= */ \"%s%s\",\n", compile_uri_prefix, 35.268 + ss->system->id); 35.269 + fprintf(fp, "\t/* .instantiate\t\t= */ instantiate_%s,\n", 35.270 + ss->system->id); 35.271 + fprintf(fp, "\t/* .connect_port\t= */ connect_port_%s,\n", 35.272 + ss->system->id); 35.273 + fprintf(fp, "\t/* .activate\t\t= */ activate_%s,\n", ss->system->id); 35.274 + fprintf(fp, "\t/* .run\t\t\t= */ run_%s,\n", ss->system->id); 35.275 + fprintf(fp, "\t/* .deactivate\t\t= */ deactivate_%s,\n", 35.276 + ss->system->id); 35.277 + fprintf(fp, "\t/* .cleanup\t\t= */ cleanup_%s,\n", ss->system->id); 35.278 + fprintf(fp, "\t/* .extension_data\t= */ NULL\n"); 35.279 + fprintf(fp, " };\n"); 35.280 +} 35.281 + 35.282 +static void 35.283 +c_print_descriptor_name(void *data, void *context) 35.284 +{ 35.285 + struct scheduled_system *ss; 35.286 + FILE *fp; 35.287 + 35.288 + ss = (struct scheduled_system *)data; 35.289 + fp = (FILE *)context; 35.290 + 35.291 + fprintf(fp, "\t&descriptor_%s,\n", ss->system->id); 35.292 +} 35.293 + 35.294 +static void 35.295 +h_compile(void *data, void *context) 35.296 +{ 35.297 + struct scheduled_system *ss; 35.298 + FILE *fp; 35.299 + 35.300 + ss = (struct scheduled_system *)data; 35.301 + 35.302 + fp = xfopenw(ss->system->id, ".h"); 35.303 + 35.304 + fprintf(fp, "#ifndef _%s_H_\n", ss->system->id); 35.305 + fprintf(fp, "#define _%s_H_\n", ss->system->id); 35.306 + 35.307 + fprintf(fp, "\n"); 35.308 + fprintf(fp, "#include <lv2.h>\n"); 35.309 + 35.310 + fprintf(fp, "\n"); 35.311 + fprintf(fp, "LV2_Handle\n"); 35.312 + fprintf(fp, "instantiate_%s(const LV2_Descriptor *descriptor,\n", 35.313 + ss->system->id); 35.314 + fprintf(fp, "\tdouble sample_rate, const char *bundle_path,\n"); 35.315 + fprintf(fp, "\tconst LV2_Feature * const *features);\n"); 35.316 + 35.317 + fprintf(fp, "\n"); 35.318 + fprintf(fp, "void\n"); 35.319 + fprintf(fp, "connect_port_%s(LV2_Handle instance, uint32_t port,\n", 35.320 + ss->system->id); 35.321 + fprintf(fp, "\tvoid *data_location);\n"); 35.322 + 35.323 + fprintf(fp, "\n"); 35.324 + fprintf(fp, "void\n"); 35.325 + fprintf(fp, "activate_%s(LV2_Handle instance);\n", ss->system->id); 35.326 + 35.327 + fprintf(fp, "\n"); 35.328 + fprintf(fp, "void\n"); 35.329 + fprintf(fp, "run_%s(LV2_Handle instance, uint32_t sample_count);\n", 35.330 + ss->system->id); 35.331 + 35.332 + fprintf(fp, "\n"); 35.333 + fprintf(fp, "void\n"); 35.334 + fprintf(fp, "deactivate_%s(LV2_Handle instance);\n", ss->system->id); 35.335 + 35.336 + fprintf(fp, "\n"); 35.337 + fprintf(fp, "void\n"); 35.338 + fprintf(fp, "cleanup_%s(LV2_Handle instance);\n", ss->system->id); 35.339 + 35.340 + fprintf(fp, "\n"); 35.341 + fprintf(fp, "#endif /* !_%s_H_ */\n", ss->system->id); 35.342 + 35.343 + fclose(fp); 35.344 +} 35.345 + 35.346 +static void 35.347 +c_instance_print_io_port(void *data, void *context) 35.348 +{ 35.349 + struct scheduled_expr *sexpr; 35.350 + FILE *fp; 35.351 + 35.352 + sexpr = (struct scheduled_expr *)data; 35.353 + fp = (FILE *)context; 35.354 + 35.355 + if (sexpr->component != NULL) 35.356 + return; 35.357 + 35.358 + fprintf(fp, "\tfloat\t*port_%s;\n", sexpr->port->id); 35.359 +} 35.360 + 35.361 +static void 35.362 +c_instance_print_buf(void *data, void *context) 35.363 +{ 35.364 + struct scheduled_expr *sexpr; 35.365 + FILE *fp; 35.366 + 35.367 + sexpr = (struct scheduled_expr *)data; 35.368 + fp = (FILE *)context; 35.369 + 35.370 + if (sexpr->db_type == delay_buf_type_none) 35.371 + return; 35.372 + 35.373 + fprintf(fp, "\n"); 35.374 + fprintf(fp, "\t/* %s%s%s%s */\n", 35.375 + (sexpr->component != NULL) ? sexpr->component->id : "", 35.376 + (sexpr->component != NULL) ? "." : "", sexpr->port->id, 35.377 + ((sexpr->port->type == port_type_w) 35.378 + || (sexpr->port->type == port_type_k)) ? ".out" : ""); 35.379 + 35.380 + if (sexpr->db_type == delay_buf_type_single) 35.381 + fprintf(fp, "\tfloat\t buf_%lu;\n", sexpr->index); 35.382 + else if (sexpr->db_type == delay_buf_type_fixed) 35.383 + { 35.384 + fprintf(fp, "\tfloat\t buf_%lu[%lu];\n", sexpr->index, 35.385 + (size_t)sexpr->delay_min + 1); 35.386 + fprintf(fp, "\tsize_t\t buf_%lu_cur;\n", sexpr->index); 35.387 + } 35.388 + else 35.389 + { 35.390 + fprintf(fp, "\tfloat\t*buf_%lu;\n", sexpr->index); 35.391 + fprintf(fp, "\tsize_t\t buf_%lu_cur;\n", sexpr->index); 35.392 + fprintf(fp, "\tsize_t\t buf_%lu_len;\n", sexpr->index); 35.393 + } 35.394 +} 35.395 + 35.396 +static void 35.397 +c_instance_print_interm(void *data, void *context) 35.398 +{ 35.399 + struct scheduled_expr *sexpr; 35.400 + FILE *fp; 35.401 + 35.402 + sexpr = (struct scheduled_expr *)data; 35.403 + fp = (FILE *)context; 35.404 + 35.405 + if (sexpr->component == NULL) 35.406 + return; 35.407 + 35.408 + if (sexpr->is_df_refd) 35.409 + { 35.410 + fprintf(fp, "\n"); 35.411 + fprintf(fp, "\t/* %s.%s%s */\n", sexpr->component->id, 35.412 + sexpr->port->id, 35.413 + ((sexpr->port->type == port_type_w) 35.414 + || (sexpr->port->type == port_type_k)) ? ".out" : ""); 35.415 + fprintf(fp, "\tfloat\t val_%lu;\n", sexpr->index); 35.416 + } 35.417 +} 35.418 + 35.419 +static void 35.420 +c_connect_port_print(void *data, void *context) 35.421 +{ 35.422 + struct scheduled_expr *sexpr; 35.423 + FILE *fp; 35.424 + 35.425 + sexpr = (struct scheduled_expr *)data; 35.426 + fp = (FILE *)context; 35.427 + 35.428 + if (sexpr->component != NULL) 35.429 + return; 35.430 + 35.431 + fprintf(fp, "\t\tcase %lu:\n", sexpr->index); 35.432 + fprintf(fp, "\t\t\tplugin->port_%s = data_location;\n", 35.433 + sexpr->port->id); 35.434 + fprintf(fp, "\t\t\tbreak;\n"); 35.435 +} 35.436 + 35.437 +struct c_instantiate_print_delays_context 35.438 + { 35.439 + size_t index; 35.440 + FILE *fp; 35.441 + }; 35.442 + 35.443 +static void 35.444 +c_instantiate_print_delays(void *data, void *context) 35.445 +{ 35.446 + struct delay *delay; 35.447 + struct c_instantiate_print_delays_context *ctx; 35.448 + 35.449 + delay = (struct delay *)data; 35.450 + ctx = (struct c_instantiate_print_delays_context *)context; 35.451 + 35.452 + fprintf(ctx->fp, "\tvalue = (size_t)ceilf(("); 35.453 + if (delay->delay_max == NULL) 35.454 + expr_c_compile(delay->delay, ctx->fp, 0); 35.455 + else 35.456 + expr_c_compile(delay->delay_max, ctx->fp, 0); 35.457 + fprintf(ctx->fp, ") + 1.0);\n"); 35.458 + fprintf(ctx->fp, "\tif (value > instance->buf_%lu_len)\n", ctx->index); 35.459 + fprintf(ctx->fp, "\t\tinstance->buf_%lu_len = value;\n", ctx->index); 35.460 +} 35.461 + 35.462 +static void 35.463 +c_instantiate_print_alloc(void *data, void *context) 35.464 +{ 35.465 + struct scheduled_expr *sexpr; 35.466 + FILE *fp; 35.467 + struct c_instantiate_print_delays_context ctx; 35.468 + 35.469 + sexpr = (struct scheduled_expr *)data; 35.470 + fp = (FILE *)context; 35.471 + 35.472 + if (sexpr->db_type != delay_buf_type_var) 35.473 + return; 35.474 + 35.475 + fprintf(fp, "\n"); 35.476 + fprintf(fp, "\tinstance->buf_%lu_len = (size_t)%.*f;\n", sexpr->index, 35.477 + DBL_DIG, sexpr->delay_min + 1.0); 35.478 + ctx.fp = fp; 35.479 + ctx.index = sexpr->index; 35.480 + list_for_each(sexpr->delays, c_instantiate_print_delays, &ctx); 35.481 + fprintf(fp, "\n"); 35.482 + fprintf(fp, "\tinstance->buf_%lu = \n" 35.483 + "\t\t(float *)malloc(instance->buf_%lu_len * sizeof(float));\n", 35.484 + sexpr->index, sexpr->index); 35.485 + fprintf(fp, "\tif (instance->buf_%lu == NULL)\n", sexpr->index); 35.486 + fprintf(fp, "\t\tgoto err_%lu;\n", sexpr->index); 35.487 +} 35.488 + 35.489 +struct c_instantiate_print_err_context 35.490 + { 35.491 + FILE *fp; 35.492 + char first; 35.493 + }; 35.494 + 35.495 +static void 35.496 +c_instantiate_print_err(void *data, void *context) 35.497 +{ 35.498 + struct scheduled_expr *sexpr; 35.499 + struct c_instantiate_print_err_context *ctx; 35.500 + 35.501 + sexpr = (struct scheduled_expr *)data; 35.502 + ctx = (struct c_instantiate_print_err_context *)context; 35.503 + 35.504 + if (sexpr->db_type != delay_buf_type_var) 35.505 + return; 35.506 + 35.507 + if (ctx->first) 35.508 + ctx->first = 0; 35.509 + else 35.510 + { 35.511 + fprintf(ctx->fp, "\tfree(instance->buf_%lu);\n", sexpr->index); 35.512 + fprintf(ctx->fp, "\n"); 35.513 + } 35.514 + fprintf(ctx->fp, "err_%lu:\n", sexpr->index); 35.515 +} 35.516 + 35.517 +static void 35.518 +c_activate_print_buf(void *data, void *context) 35.519 +{ 35.520 + struct scheduled_expr *sexpr; 35.521 + FILE *fp; 35.522 + 35.523 + sexpr = (struct scheduled_expr *)data; 35.524 + fp = (FILE *)context; 35.525 + 35.526 + if (sexpr->db_type == delay_buf_type_none) 35.527 + return; 35.528 + 35.529 + fprintf(fp, "\n"); 35.530 + 35.531 + if (sexpr->db_type == delay_buf_type_single) 35.532 + fprintf(fp, "\tplugin->buf_%lu = 0.0;\n", sexpr->index); 35.533 + else if (sexpr->db_type == delay_buf_type_fixed) 35.534 + { 35.535 + fprintf(fp, "\tmemset(plugin->buf_%lu, 0, %lu * " 35.536 + "sizeof(float));\n", sexpr->index, 35.537 + (size_t)sexpr->delay_min + 1); 35.538 + fprintf(fp, "\tplugin->buf_%lu_cur = 0;\n", sexpr->index); 35.539 + } 35.540 + else if (sexpr->db_type == delay_buf_type_var) 35.541 + { 35.542 + fprintf(fp, "\tmemset(plugin->buf_%lu, 0, " 35.543 + "plugin->buf_%lu_len * sizeof(float));\n", sexpr->index, 35.544 + sexpr->index); 35.545 + fprintf(fp, "\tplugin->buf_%lu_cur = 0;\n", sexpr->index); 35.546 + } 35.547 +} 35.548 + 35.549 +static void 35.550 +c_activate_print_interm(void *data, void *context) 35.551 +{ 35.552 + struct scheduled_expr *sexpr; 35.553 + FILE *fp; 35.554 + 35.555 + sexpr = (struct scheduled_expr *)data; 35.556 + fp = (FILE *)context; 35.557 + 35.558 + if (sexpr->component == NULL) 35.559 + return; 35.560 + 35.561 + if (sexpr->is_df_refd) 35.562 + fprintf(fp, "\tplugin->val_%lu = 0.0;\n", sexpr->index); 35.563 +} 35.564 + 35.565 +static void 35.566 +c_run_print_sexpr(void *data, void *context) 35.567 +{ 35.568 + struct scheduled_expr *sexpr; 35.569 + FILE *fp; 35.570 + 35.571 + sexpr = (struct scheduled_expr *)data; 35.572 + fp = (FILE *)context; 35.573 + 35.574 + if (((sexpr->component == NULL) && !sexpr->is_output) 35.575 + || ((sexpr->component != NULL) && !sexpr->is_df_refd)) 35.576 + return; 35.577 + 35.578 + if (sexpr->component == NULL) 35.579 + fprintf(fp, "\t\tplugin->port_%s%s = ", sexpr->port->id, 35.580 + (sexpr->port->sync == port_sync_sync) ? "[i]" : "[0]"); 35.581 + else 35.582 + fprintf(fp, "\t\tplugin->val_%lu = ", sexpr->index); 35.583 + expr_c_compile(sexpr->expr, fp, 1); 35.584 + fprintf(fp, ";\n"); 35.585 +} 35.586 + 35.587 +static void 35.588 +c_run_print_buf_update(void *data, void *context) 35.589 +{ 35.590 + struct scheduled_expr *sexpr; 35.591 + FILE *fp; 35.592 + 35.593 + sexpr = (struct scheduled_expr *)data; 35.594 + fp = (FILE *)context; 35.595 + 35.596 + if (sexpr->db_type == delay_buf_type_none) 35.597 + return; 35.598 + else if (sexpr->db_type == delay_buf_type_single) 35.599 + fprintf(fp, "\t\tplugin->buf_%lu = ", sexpr->index); 35.600 + else 35.601 + fprintf(fp, "\t\tplugin->buf_%lu[plugin->buf_%lu_cur] = ", 35.602 + sexpr->index, sexpr->index); 35.603 + 35.604 + if ((sexpr->component == NULL) && !sexpr->is_output) 35.605 + fprintf(fp, "plugin->port_%s%s", sexpr->port->id, 35.606 + (sexpr->port->sync == port_sync_sync) ? "[i]" : "[0]"); 35.607 + else 35.608 + expr_c_compile(sexpr->expr, fp, 1); 35.609 + fprintf(fp, ";\n"); 35.610 +} 35.611 + 35.612 +static void 35.613 +c_run_print_cur_update(void *data, void *context) 35.614 +{ 35.615 + struct scheduled_expr *sexpr; 35.616 + FILE *fp; 35.617 + 35.618 + sexpr = (struct scheduled_expr *)data; 35.619 + fp = (FILE *)context; 35.620 + 35.621 + if ((sexpr->db_type == delay_buf_type_none) 35.622 + || (sexpr->db_type == delay_buf_type_single)) 35.623 + return; 35.624 + 35.625 + fprintf(fp, "\t\tplugin->buf_%lu_cur++;\n", sexpr->index); 35.626 + 35.627 + if (sexpr->db_type == delay_buf_type_fixed) 35.628 + fprintf(fp, "\t\tplugin->buf_%lu_cur %%= %lu;\n", 35.629 + sexpr->index, (size_t)sexpr->delay_min + 1); 35.630 + else 35.631 + fprintf(fp, "\t\tplugin->buf_%lu_cur %%= " 35.632 + "plugin->buf_%lu_len;\n", sexpr->index, sexpr->index); 35.633 +} 35.634 + 35.635 +static void 35.636 +c_cleanup_print_free(void *data, void *context) 35.637 +{ 35.638 + struct scheduled_expr *sexpr; 35.639 + FILE *fp; 35.640 + 35.641 + sexpr = (struct scheduled_expr *)data; 35.642 + fp = (FILE *)context; 35.643 + 35.644 + if (sexpr->db_type != delay_buf_type_var) 35.645 + return; 35.646 + 35.647 + fprintf(fp, "\tfree(plugin->buf_%lu);\n", sexpr->index); 35.648 +} 35.649 + 35.650 +static void 35.651 +req_interm(void *data, void *context) 35.652 +{ 35.653 + struct scheduled_expr *sexpr; 35.654 + char *ret; 35.655 + 35.656 + sexpr = (struct scheduled_expr *)data; 35.657 + ret = (char *)context; 35.658 + 35.659 + if ((sexpr->component != NULL) && !*ret && (sexpr->is_df_refd)) 35.660 + *ret = 1; 35.661 +} 35.662 + 35.663 +static char 35.664 +system_has_interm(struct scheduled_system *ss) 35.665 +{ 35.666 + char ret; 35.667 + 35.668 + ret = 0; 35.669 + list_for_each(ss->exprs, req_interm, &ret); 35.670 + 35.671 + return ret; 35.672 +} 35.673 + 35.674 +static void 35.675 +merge_include(void *data, void *context) 35.676 +{ 35.677 + struct ext_func *func; 35.678 + list_t includes; 35.679 + 35.680 + func = (struct ext_func *)data; 35.681 + includes = (list_t)context; 35.682 + 35.683 + if (func->include[0] != '\0') 35.684 + if (list_find(includes, (int (*)(void *, void *))strcmp, 35.685 + func->include) == NULL) 35.686 + list_append(includes, func->include); 35.687 +} 35.688 + 35.689 +static void 35.690 +add_include(void *data, void *context) 35.691 +{ 35.692 + struct scheduled_expr *sexpr; 35.693 + list_t includes; 35.694 + list_t l; 35.695 + 35.696 + sexpr = (struct scheduled_expr *)data; 35.697 + includes = (list_t)context; 35.698 + 35.699 + if ((sexpr->component == NULL) & !sexpr->is_output) 35.700 + return; 35.701 + 35.702 + l = expr_get_ext_funcs(sexpr->expr); 35.703 + list_for_each(l, merge_include, includes); 35.704 + list_free(l); 35.705 +} 35.706 + 35.707 +static void 35.708 +c_plugin_print_include(void *data, void *context) 35.709 +{ 35.710 + char *inc; 35.711 + FILE *fp; 35.712 + 35.713 + inc = (char *)data; 35.714 + fp = (FILE *)context; 35.715 + 35.716 + fprintf(fp, "#include \"%s\"\n", inc); 35.717 +} 35.718 + 35.719 +static void 35.720 +c_compile(void *data, void *context) 35.721 +{ 35.722 + struct scheduled_system *ss; 35.723 + FILE *fp; 35.724 + struct c_instantiate_print_err_context e_ctx; 35.725 + char c; 35.726 + list_t includes; 35.727 + 35.728 + ss = (struct scheduled_system *)data; 35.729 + 35.730 + includes = list_new(); 35.731 + if (ss->has_var_delay || ss->has_fixed_delay) 35.732 + list_append(includes, "math.h"); 35.733 + list_for_each(ss->schedule, add_include, includes); 35.734 + 35.735 + fp = xfopenw(ss->system->id, ".c"); 35.736 + 35.737 + fprintf(fp, "#include <stddef.h>\n"); 35.738 + fprintf(fp, "#include <stdlib.h>\n"); 35.739 + fprintf(fp, "#include <string.h>\n"); 35.740 + if (!list_is_empty(includes)) 35.741 + { 35.742 + fprintf(fp, "\n"); 35.743 + list_for_each(includes, c_plugin_print_include, fp); 35.744 + 35.745 + } 35.746 + fprintf(fp, "\n"); 35.747 + fprintf(fp, "#include <lv2.h>\n"); 35.748 + fprintf(fp, "\n"); 35.749 + fprintf(fp, "#include \"%s.h\"\n", ss->system->id); 35.750 + 35.751 + fprintf(fp, "\n"); 35.752 + fprintf(fp, "struct instance\n"); 35.753 + fprintf(fp, " {\n"); 35.754 + if (ss->uses_sample_rate) 35.755 + { 35.756 + fprintf(fp, "\t/* Sample rate */\n"); 35.757 + fprintf(fp, "\tdouble\t sample_rate;\n"); 35.758 + fprintf(fp, "\n"); 35.759 + } 35.760 + fprintf(fp, "\t/* Port connections */\n"); 35.761 + list_for_each_rev(ss->exprs, c_instance_print_io_port, fp); 35.762 + fprintf(fp, "\n"); 35.763 + fprintf(fp, "\t/* Internal buffers */\n"); 35.764 + list_for_each(ss->exprs, c_instance_print_buf, fp); 35.765 + fprintf(fp, "\n"); 35.766 + fprintf(fp, "\t/* Intermediate values */\n"); 35.767 + list_for_each(ss->exprs, c_instance_print_interm, fp); 35.768 + fprintf(fp, " };\n"); 35.769 + 35.770 + if (ss->has_fixed_delay || ss->has_var_delay) 35.771 + { 35.772 + fprintf(fp, "\n"); 35.773 + fprintf(fp, "static unsigned long\n"); 35.774 + fprintf(fp, "pmf_delay(float n, unsigned long cur, " 35.775 + "unsigned long max)\n"); 35.776 + fprintf(fp, "{\n"); 35.777 + fprintf(fp, "\tlong u;\n"); 35.778 + fprintf(fp, "\n"); 35.779 + fprintf(fp, "\tu = roundf(n);\n"); 35.780 + fprintf(fp, "\n"); 35.781 + fprintf(fp, "\tif (u < 1)\n"); 35.782 + fprintf(fp, "\t\tu = 1;\n"); 35.783 + fprintf(fp, "\tif (u > max)\n"); 35.784 + fprintf(fp, "\t\tu = max;\n"); 35.785 + fprintf(fp, "\n"); 35.786 + fprintf(fp, "\tu = ((long)cur - u) %% ((long)max + 1);\n"); 35.787 + fprintf(fp, "\tif (u < 0)\n"); 35.788 + fprintf(fp, "\t\tu += max + 1;\n"); 35.789 + fprintf(fp, "\n"); 35.790 + fprintf(fp, "\treturn u;\n"); 35.791 + fprintf(fp, "}\n"); 35.792 + } 35.793 + 35.794 + fprintf(fp, "\n"); 35.795 + fprintf(fp, "LV2_Handle\n"); 35.796 + fprintf(fp, "instantiate_%s(const LV2_Descriptor *descriptor,\n", 35.797 + ss->system->id); 35.798 + fprintf(fp, "\tdouble sample_rate, const char *bundle_path,\n"); 35.799 + fprintf(fp, "\tconst LV2_Feature * const *features)\n"); 35.800 + fprintf(fp, "{\n"); 35.801 + fprintf(fp, "\tstruct instance *instance;\n"); 35.802 + if (ss->has_var_delay) 35.803 + fprintf(fp, "\tsize_t value;\n"); 35.804 + fprintf(fp, "\n"); 35.805 + fprintf(fp, "\tinstance = " 35.806 + "(struct instance *)malloc(sizeof(struct instance));\n"); 35.807 + fprintf(fp, "\tif (instance == NULL)\n"); 35.808 + fprintf(fp, "\t\treturn NULL;\n"); 35.809 + if (ss->has_var_delay) 35.810 + list_for_each(ss->exprs, c_instantiate_print_alloc ,fp); 35.811 + if (ss->uses_sample_rate) 35.812 + { 35.813 + fprintf(fp, "\n"); 35.814 + fprintf(fp, "\tinstance->sample_rate = sample_rate;\n"); 35.815 + } 35.816 + fprintf(fp, "\n"); 35.817 + fprintf(fp, "\treturn instance;\n"); 35.818 + if (ss->has_var_delay) 35.819 + { 35.820 + fprintf(fp, "\n"); 35.821 + e_ctx.fp = fp; 35.822 + e_ctx.first = 1; 35.823 + list_for_each(ss->exprs, c_instantiate_print_err, &e_ctx); 35.824 + fprintf(fp, "\tfree(instance);\n"); 35.825 + fprintf(fp, "\n"); 35.826 + fprintf(fp, "\treturn NULL;\n"); 35.827 + } 35.828 + fprintf(fp, "}\n"); 35.829 + 35.830 + fprintf(fp, "\n"); 35.831 + fprintf(fp, "void\n"); 35.832 + fprintf(fp, "connect_port_%s(LV2_Handle instance, uint32_t port,\n", 35.833 + ss->system->id); 35.834 + fprintf(fp, "\tvoid *data_location)\n"); 35.835 + fprintf(fp, "{\n"); 35.836 + fprintf(fp, "\tstruct instance *plugin;\n"); 35.837 + fprintf(fp, "\n"); 35.838 + fprintf(fp, "\tplugin = (struct instance *)instance;\n"); 35.839 + fprintf(fp, "\n"); 35.840 + fprintf(fp, "\tswitch (port)\n"); 35.841 + fprintf(fp, "\t {\n"); 35.842 + list_for_each_rev(ss->exprs, c_connect_port_print, fp); 35.843 + fprintf(fp, "\t }\n"); 35.844 + fprintf(fp, "}\n"); 35.845 + 35.846 + fprintf(fp, "\n"); 35.847 + fprintf(fp, "void\n"); 35.848 + fprintf(fp, "activate_%s(LV2_Handle instance)\n", ss->system->id); 35.849 + fprintf(fp, "{\n"); 35.850 + c = system_has_interm(ss); 35.851 + if (ss->has_single_delay || ss->has_fixed_delay || ss->has_var_delay 35.852 + || c) 35.853 + { 35.854 + fprintf(fp, "\tstruct instance *plugin;\n"); 35.855 + fprintf(fp, "\n"); 35.856 + fprintf(fp, "\tplugin = (struct instance *)instance;\n"); 35.857 + } 35.858 + if (ss->has_single_delay || ss->has_fixed_delay || ss->has_var_delay) 35.859 + list_for_each(ss->exprs, c_activate_print_buf, fp); 35.860 + if (c) 35.861 + { 35.862 + fprintf(fp, "\n"); 35.863 + list_for_each(ss->exprs, c_activate_print_interm, fp); 35.864 + } 35.865 + fprintf(fp, "}\n"); 35.866 + 35.867 + fprintf(fp, "\n"); 35.868 + fprintf(fp, "void\n"); 35.869 + fprintf(fp, "run_%s(LV2_Handle instance, uint32_t sample_count)\n", 35.870 + ss->system->id); 35.871 + fprintf(fp, "{\n"); 35.872 + fprintf(fp, "\tstruct instance *plugin;\n"); 35.873 + fprintf(fp, "\tuint32_t i;\n"); 35.874 + fprintf(fp, "\n"); 35.875 + fprintf(fp, "\tplugin = (struct instance *)instance;\n"); 35.876 + fprintf(fp, "\n"); 35.877 + fprintf(fp, "\tfor (i = 0; i < sample_count; i++)\n"); 35.878 + fprintf(fp, "\t {\n"); 35.879 + list_for_each(ss->schedule, c_run_print_sexpr, fp); 35.880 + if (ss->has_single_delay || ss->has_fixed_delay || ss->has_var_delay) 35.881 + { 35.882 + fprintf(fp, "\n"); 35.883 + fprintf(fp, "\t\t/* Update buffers */\n"); 35.884 + list_for_each_rev(ss->schedule, c_run_print_buf_update, fp); 35.885 + } 35.886 + if (ss->has_fixed_delay || ss->has_var_delay) 35.887 + { 35.888 + fprintf(fp, "\n"); 35.889 + fprintf(fp, "\t\t/* Update current buffer positions */\n"); 35.890 + list_for_each_rev(ss->schedule, c_run_print_cur_update, fp); 35.891 + } 35.892 + fprintf(fp, "\t }\n"); 35.893 + fprintf(fp, "}\n"); 35.894 + fflush(fp); 35.895 + 35.896 + fprintf(fp, "\n"); 35.897 + fprintf(fp, "void\n"); 35.898 + fprintf(fp, "deactivate_%s(LV2_Handle instance)\n", ss->system->id); 35.899 + fprintf(fp, "{\n"); 35.900 + fprintf(fp, "}\n"); 35.901 + fflush(fp); 35.902 + 35.903 + fprintf(fp, "\n"); 35.904 + fprintf(fp, "void\n"); 35.905 + fprintf(fp, "cleanup_%s(LV2_Handle instance)\n", ss->system->id); 35.906 + fprintf(fp, "{\n"); 35.907 + if (ss->has_var_delay) 35.908 + { 35.909 + fprintf(fp, "\tstruct instance *plugin;\n"); 35.910 + fprintf(fp, "\n"); 35.911 + fprintf(fp, "\tplugin = (struct instance *)instance;\n"); 35.912 + fprintf(fp, "\n"); 35.913 + list_for_each_rev(ss->exprs, c_cleanup_print_free, fp); 35.914 + fprintf(fp, "\n"); 35.915 + } 35.916 + fprintf(fp, "\tfree(instance);\n"); 35.917 + fprintf(fp, "}\n"); 35.918 + 35.919 + fclose(fp); 35.920 +} 35.921 + 35.922 +static void 35.923 +mk_print_objs(void *data, void *context) 35.924 +{ 35.925 + struct scheduled_system *ss; 35.926 + FILE *fp; 35.927 + 35.928 + ss = (struct scheduled_system *)data; 35.929 + fp = (FILE *)context; 35.930 + 35.931 + fprintf(fp, " %s.o", ss->system->id); 35.932 +} 35.933 + 35.934 +static void 35.935 +check_need_libm(void *data, void *context) 35.936 +{ 35.937 + struct scheduled_system *ss; 35.938 + list_t libs; 35.939 + 35.940 + ss = (struct scheduled_system *)data; 35.941 + libs = (list_t)context; 35.942 + 35.943 + if (ss->has_var_delay || ss->has_fixed_delay) 35.944 + if (list_find(libs, (int (*)(void *, void *))strcmp, "m") 35.945 + == NULL) 35.946 + list_append(libs, "m"); 35.947 +} 35.948 + 35.949 +static void 35.950 +mk_print_libs(void *data, void *context) 35.951 +{ 35.952 + char *lib; 35.953 + FILE *fp; 35.954 + 35.955 + lib = (char *)data; 35.956 + fp = (FILE *)context; 35.957 + 35.958 + fprintf(fp, " -l%s", lib); 35.959 +} 35.960 + 35.961 +static void 35.962 +merge_libs(void *data, void *context) 35.963 +{ 35.964 + struct ext_func *func; 35.965 + list_t libs; 35.966 + 35.967 + func = (struct ext_func *)data; 35.968 + libs = (list_t)context; 35.969 + 35.970 + if (func->lib[0] != '\0') 35.971 + if (list_find(libs, (int (*)(void *, void *))strcmp, func->lib) 35.972 + == NULL) 35.973 + list_append(libs, func->lib); 35.974 +} 35.975 + 35.976 +static void 35.977 +sexpr_add_libs(void *data, void *context) 35.978 +{ 35.979 + struct scheduled_expr *sexpr; 35.980 + list_t funcs; 35.981 + 35.982 + sexpr = (struct scheduled_expr *)data; 35.983 + 35.984 + if ((sexpr->component == NULL) && !sexpr->is_output) 35.985 + return; 35.986 + 35.987 + funcs = expr_get_ext_funcs(sexpr->expr); 35.988 + list_for_each(funcs, merge_libs, context); 35.989 + list_free(funcs); 35.990 +} 35.991 + 35.992 +static void 35.993 +add_libs(void *data, void *context) 35.994 +{ 35.995 + struct scheduled_system *ss; 35.996 + 35.997 + ss = (struct scheduled_system *)data; 35.998 + 35.999 + list_for_each(ss->schedule, sexpr_add_libs, context); 35.1000 +} 35.1001 + 35.1002 +void 35.1003 +compile(list_t systems) 35.1004 +{ 35.1005 + FILE *fp; 35.1006 + list_t libs; 35.1007 + 35.1008 + if (compile_gen_manifest) 35.1009 + { 35.1010 + fp = xfopenw("manifest.ttl", NULL); 35.1011 + 35.1012 + fprintf(fp, "@prefix lv2: <http://lv2plug.in/ns/lv2core#> " 35.1013 + ".\n"); 35.1014 + fprintf(fp, "@prefix rdfs: " 35.1015 + "<http://www.w3.org/2000/01/rdf-schema#> .\n"); 35.1016 + list_for_each(systems, manifest_print_plugin, fp); 35.1017 + 35.1018 + fclose(fp); 35.1019 + } 35.1020 + 35.1021 + if (compile_gen_plugin_ttl) 35.1022 + list_for_each(systems, ttl_compile, NULL); 35.1023 + 35.1024 + if (compile_gen_extra_ttl) 35.1025 + list_for_each(systems, ttl_extra_compile, NULL); 35.1026 + 35.1027 + if (compile_gen_descriptor) 35.1028 + { 35.1029 + fp = xfopenw("lv2_descriptor.c", NULL); 35.1030 + 35.1031 + fprintf(fp, "#include <stddef.h>\n"); 35.1032 + fprintf(fp, "\n"); 35.1033 + fprintf(fp, "#include <lv2.h>\n"); 35.1034 + fprintf(fp, "\n"); 35.1035 + list_for_each(systems, c_print_include, fp); 35.1036 + 35.1037 + list_for_each(systems, c_print_descriptor, fp); 35.1038 + 35.1039 + fprintf(fp, "\n"); 35.1040 + fprintf(fp, "static const LV2_Descriptor * descriptors[] =\n"); 35.1041 + fprintf(fp, " {\n"); 35.1042 + list_for_each(systems, c_print_descriptor_name, fp); 35.1043 + fprintf(fp, " };\n"); 35.1044 + 35.1045 + fprintf(fp, "\n"); 35.1046 + fprintf(fp, "LV2_SYMBOL_EXPORT\n"); 35.1047 + fprintf(fp, "const LV2_Descriptor *lv2_descriptor(uint32_t " 35.1048 + "index)\n"); 35.1049 + fprintf(fp, "{\n"); 35.1050 + fprintf(fp, "\tif (index >= (sizeof(descriptors) / " 35.1051 + "sizeof(const LV2_Descriptor *)))\n"); 35.1052 + fprintf(fp, "\t\treturn NULL;\n"); 35.1053 + fprintf(fp, "\n"); 35.1054 + fprintf(fp, "\treturn descriptors[index];\n"); 35.1055 + fprintf(fp, "}\n"); 35.1056 + 35.1057 + fclose(fp); 35.1058 + } 35.1059 + 35.1060 + if (compile_gen_code) 35.1061 + { 35.1062 + list_for_each(systems, h_compile, NULL); 35.1063 + list_for_each(systems, c_compile, NULL); 35.1064 + } 35.1065 + 35.1066 + if (compile_gen_makefile) 35.1067 + { 35.1068 + libs = list_new(); 35.1069 + list_for_each(systems, check_need_libm, libs); 35.1070 + list_for_each(systems, add_libs, libs); 35.1071 + 35.1072 + fp = xfopenw("Makefile", NULL); 35.1073 + 35.1074 + fprintf(fp, "CFLAGS = -fPIC\n"); 35.1075 + fprintf(fp, "LIBS ="); 35.1076 + list_for_each(libs, mk_print_libs, fp); 35.1077 + fprintf(fp, "\n"); 35.1078 + fprintf(fp, "SO_EXT = .so\n"); 35.1079 + list_free(libs); 35.1080 + 35.1081 + fprintf(fp, "\n"); 35.1082 + fprintf(fp, "OBJS = lv2_descriptor.o"); 35.1083 + list_for_each(systems, mk_print_objs, fp); 35.1084 + fprintf(fp, "\n"); 35.1085 + 35.1086 + fprintf(fp, "\n"); 35.1087 + fprintf(fp, "all: plugin.so\n"); 35.1088 + 35.1089 + fprintf(fp, "\n"); 35.1090 + fprintf(fp, "plugin$(SO_EXT): $(OBJS)\n"); 35.1091 + fprintf(fp, "\t$(LD) $(OBJS) -o plugin$(SO_EXT) -shared " 35.1092 + "$(LIBS)"); 35.1093 + fprintf(fp, "\n"); 35.1094 + 35.1095 + fprintf(fp, "\n"); 35.1096 + fprintf(fp, "clean:\n"); 35.1097 + fprintf(fp, "\trm -f *.o plugin$(SO_EXT)\n"); 35.1098 + 35.1099 + fclose(fp); 35.1100 + } 35.1101 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/permafrost/src/compile.h Sun May 02 14:19:58 2010 +0300 36.3 @@ -0,0 +1,27 @@ 36.4 +/* 36.5 + * Permafrost - Physical modelling framework 36.6 + * 36.7 + * Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 36.8 + * 36.9 + * See the COPYING file for license conditions. 36.10 + */ 36.11 + 36.12 +#ifndef _COMPILE_H_ 36.13 +#define _COMPILE_H_ 36.14 + 36.15 +#include "src/types.h" 36.16 + 36.17 +char *compile_output_dir; 36.18 +char compile_gen_code; 36.19 +char compile_gen_descriptor; 36.20 +char compile_gen_makefile; 36.21 +char compile_gen_manifest; 36.22 +char compile_gen_plugin_ttl; 36.23 +char compile_gen_extra_ttl; 36.24 +char *compile_uri_prefix; 36.25 +char *compile_license_uri; 36.26 + 36.27 +void 36.28 +compile(list_t systems); 36.29 + 36.30 +#endif /* !_COMPILE_H_ */
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/permafrost/src/expr.c Sun May 02 14:19:58 2010 +0300 37.3 @@ -0,0 +1,1778 @@ 37.4 +/* 37.5 + * Permafrost - Physical modelling framework 37.6 + * 37.7 + * Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 37.8 + * 37.9 + * See the COPYING file for license conditions. 37.10 + */ 37.11 + 37.12 +#include <stdlib.h> 37.13 +#include <stdio.h> 37.14 +#include <string.h> 37.15 +#include <float.h> 37.16 + 37.17 +#include "src/types.h" 37.18 +#include "src/list.h" 37.19 +#include "src/util.h" 37.20 +#include "src/expr.h" 37.21 + 37.22 +enum elem_type 37.23 + { 37.24 + elem_type_value, 37.25 + elem_type_sample_rate, 37.26 + elem_type_signal_id, 37.27 + elem_type_signal_port, 37.28 + elem_type_signal_ref, 37.29 + elem_type_add, 37.30 + elem_type_sub, 37.31 + elem_type_mul, 37.32 + elem_type_div, 37.33 + elem_type_plus, 37.34 + elem_type_minus, 37.35 + elem_type_call_id, 37.36 + elem_type_call_ext_func 37.37 + }; 37.38 + 37.39 +struct elem 37.40 + { 37.41 + enum elem_type type; 37.42 + union 37.43 + { 37.44 + double value; 37.45 + struct 37.46 + { 37.47 + struct expr_signal_id id; 37.48 + struct port *port; 37.49 + struct scheduled_expr *ref; 37.50 + expr_t delay; 37.51 + expr_t delay_max; 37.52 + } signal; 37.53 + struct 37.54 + { 37.55 + char *id; 37.56 + struct ext_func *ext_func; 37.57 + list_t args; 37.58 + } func; 37.59 + } v; 37.60 + }; 37.61 + 37.62 +struct _expr 37.63 + { 37.64 + list_t stack; 37.65 + }; 37.66 + 37.67 +expr_t 37.68 +expr_new_value(double value) 37.69 +{ 37.70 + struct _expr *ret; 37.71 + struct elem *elem; 37.72 + 37.73 + ret = xmalloc(sizeof(struct _expr)); 37.74 + elem = xmalloc(sizeof(struct elem)); 37.75 + ret->stack = list_new(); 37.76 + 37.77 + elem->type = elem_type_value; 37.78 + elem->v.value = value; 37.79 + 37.80 + list_push(ret->stack, elem); 37.81 + 37.82 + return ret; 37.83 +} 37.84 + 37.85 +expr_t 37.86 +expr_new_sample_rate() 37.87 +{ 37.88 + struct _expr *ret; 37.89 + struct elem *elem; 37.90 + 37.91 + ret = xmalloc(sizeof(struct _expr)); 37.92 + elem = xmalloc(sizeof(struct elem)); 37.93 + ret->stack = list_new(); 37.94 + 37.95 + elem->type = elem_type_sample_rate; 37.96 + 37.97 + list_push(ret->stack, elem); 37.98 + 37.99 + return ret; 37.100 +} 37.101 + 37.102 +expr_t 37.103 +expr_new_signal(char *id, char in, expr_t delay, expr_t delay_max) 37.104 +{ 37.105 + struct _expr *ret; 37.106 + struct elem *elem; 37.107 + 37.108 + ret = xmalloc(sizeof(struct _expr)); 37.109 + elem = xmalloc(sizeof(struct elem)); 37.110 + ret->stack = list_new(); 37.111 + 37.112 + elem->type = elem_type_signal_id; 37.113 + elem->v.signal.id.id = id; 37.114 + elem->v.signal.id.in = in; 37.115 + elem->v.signal.delay = delay; 37.116 + elem->v.signal.delay_max = delay_max; 37.117 + 37.118 + list_push(ret->stack, elem); 37.119 + 37.120 + return ret; 37.121 +} 37.122 + 37.123 +expr_t 37.124 +expr_new_signal_ref(struct scheduled_expr *ref, expr_t delay, expr_t delay_max) 37.125 +{ 37.126 + struct _expr *ret; 37.127 + struct elem *elem; 37.128 + 37.129 + ret = xmalloc(sizeof(struct _expr)); 37.130 + elem = xmalloc(sizeof(struct elem)); 37.131 + ret->stack = list_new(); 37.132 + 37.133 + elem->type = elem_type_signal_ref; 37.134 + elem->v.signal.ref = ref; 37.135 + elem->v.signal.delay = delay; 37.136 + elem->v.signal.delay_max = delay_max; 37.137 + 37.138 + list_push(ret->stack, elem); 37.139 + 37.140 + return ret; 37.141 +} 37.142 + 37.143 +expr_t 37.144 +expr_new_call(char *id, list_t args) 37.145 +{ 37.146 + struct _expr *ret; 37.147 + struct elem *elem; 37.148 + 37.149 + ret = xmalloc(sizeof(struct _expr)); 37.150 + elem = xmalloc(sizeof(struct elem)); 37.151 + ret->stack = list_new(); 37.152 + 37.153 + elem->type = elem_type_call_id; 37.154 + elem->v.func.id = id; 37.155 + elem->v.func.args = args; 37.156 + 37.157 + list_push(ret->stack, elem); 37.158 + 37.159 + return ret; 37.160 +} 37.161 + 37.162 +void 37.163 +expr_push_add(expr_t expr, expr_t expr2) 37.164 +{ 37.165 + struct elem *elem; 37.166 + 37.167 + elem = xmalloc(sizeof(struct elem)); 37.168 + 37.169 + elem->type = elem_type_add; 37.170 + 37.171 + list_merge(expr2->stack, expr->stack); 37.172 + expr->stack = expr2->stack; 37.173 + list_push(expr->stack, elem); 37.174 + 37.175 + free(expr2); 37.176 +} 37.177 + 37.178 +void 37.179 +expr_push_sub(expr_t expr, expr_t expr2) 37.180 +{ 37.181 + struct elem *elem; 37.182 + 37.183 + elem = xmalloc(sizeof(struct elem)); 37.184 + 37.185 + elem->type = elem_type_sub; 37.186 + 37.187 + list_merge(expr2->stack, expr->stack); 37.188 + expr->stack = expr2->stack; 37.189 + list_push(expr->stack, elem); 37.190 + 37.191 + free(expr2); 37.192 +} 37.193 + 37.194 +void 37.195 +expr_push_mul(expr_t expr, expr_t expr2) 37.196 +{ 37.197 + struct elem *elem; 37.198 + 37.199 + elem = xmalloc(sizeof(struct elem)); 37.200 + 37.201 + elem->type = elem_type_mul; 37.202 + 37.203 + list_merge(expr2->stack, expr->stack); 37.204 + expr->stack = expr2->stack; 37.205 + list_push(expr->stack, elem); 37.206 + 37.207 + free(expr2); 37.208 +} 37.209 + 37.210 +void 37.211 +expr_push_div(expr_t expr, expr_t expr2) 37.212 +{ 37.213 + struct elem *elem; 37.214 + 37.215 + elem = xmalloc(sizeof(struct elem)); 37.216 + 37.217 + elem->type = elem_type_div; 37.218 + 37.219 + list_merge(expr2->stack, expr->stack); 37.220 + expr->stack = expr2->stack; 37.221 + list_push(expr->stack, elem); 37.222 + 37.223 + free(expr2); 37.224 +} 37.225 + 37.226 +void 37.227 +expr_push_plus(expr_t expr) 37.228 +{ 37.229 + struct elem *elem; 37.230 + 37.231 + elem = xmalloc(sizeof(struct elem)); 37.232 + 37.233 + elem->type = elem_type_plus; 37.234 + 37.235 + list_push(expr->stack, elem); 37.236 +} 37.237 + 37.238 +void 37.239 +expr_push_minus(expr_t expr) 37.240 +{ 37.241 + struct elem *elem; 37.242 + 37.243 + elem = xmalloc(sizeof(struct elem)); 37.244 + 37.245 + elem->type = elem_type_minus; 37.246 + 37.247 + list_push(expr->stack, elem); 37.248 +} 37.249 + 37.250 +char 37.251 +expr_top_is_sign(expr_t expr) 37.252 +{ 37.253 + struct elem *elem; 37.254 + 37.255 + elem = list_get_last_data(expr->stack); 37.256 + 37.257 + return (elem->type == elem_type_plus) 37.258 + || (elem->type == elem_type_minus); 37.259 +} 37.260 + 37.261 +static int 37.262 +port_cmp_id(void *p, void *id) 37.263 +{ 37.264 + return strcmp(((struct port *)p)->id, (char *)id); 37.265 +} 37.266 + 37.267 +struct bind_to_ports_args_context 37.268 + { 37.269 + list_t ports; 37.270 + struct expr_signal_id *id; 37.271 + }; 37.272 + 37.273 +static void 37.274 +bind_to_ports_args(void *data, void *context) 37.275 +{ 37.276 + expr_t expr; 37.277 + struct bind_to_ports_args_context *ctx; 37.278 + 37.279 + expr = (expr_t)data; 37.280 + ctx = (struct bind_to_ports_args_context *)context; 37.281 + 37.282 + ctx->id = expr_bind_to_ports(expr, ctx->ports); 37.283 +} 37.284 + 37.285 +struct bind_to_ports_context 37.286 + { 37.287 + struct expr_signal_id *id; 37.288 + list_t ports; 37.289 + }; 37.290 + 37.291 +static void 37.292 +bind_to_ports(void *data, void *context) 37.293 +{ 37.294 + struct elem *elem; 37.295 + struct bind_to_ports_context *ctx; 37.296 + struct port *port; 37.297 + struct bind_to_ports_args_context a_ctx; 37.298 + 37.299 + elem = (struct elem *)data; 37.300 + ctx = (struct bind_to_ports_context *)context; 37.301 + 37.302 + if (ctx->id != NULL) 37.303 + return; 37.304 + 37.305 + if ((elem->type == elem_type_signal_id) 37.306 + || (elem->type == elem_type_signal_port) 37.307 + || (elem->type == elem_type_signal_ref)) 37.308 + { 37.309 + if (elem->v.signal.delay != NULL) 37.310 + { 37.311 + ctx->id = expr_bind_to_ports(elem->v.signal.delay, 37.312 + ctx->ports); 37.313 + if (ctx->id != NULL) 37.314 + return; 37.315 + } 37.316 + if (elem->v.signal.delay_max != NULL) 37.317 + { 37.318 + ctx->id = expr_bind_to_ports(elem->v.signal.delay_max, 37.319 + ctx->ports); 37.320 + if (ctx->id != NULL) 37.321 + return; 37.322 + } 37.323 + } 37.324 + else if ((elem->type == elem_type_call_id) 37.325 + || (elem->type == elem_type_call_ext_func)) 37.326 + { 37.327 + a_ctx.ports = ctx->ports; 37.328 + a_ctx.id = NULL; 37.329 + list_for_each(elem->v.func.args, bind_to_ports_args, &a_ctx); 37.330 + 37.331 + if (a_ctx.id != NULL) 37.332 + { 37.333 + ctx->id = a_ctx.id; 37.334 + return; 37.335 + } 37.336 + } 37.337 + 37.338 + if (elem->type != elem_type_signal_id) 37.339 + return; 37.340 + 37.341 + port = list_find(ctx->ports, port_cmp_id, elem->v.signal.id.id); 37.342 + if (port == NULL) 37.343 + return; 37.344 + 37.345 + if ((elem->v.signal.id.in && (port->type != port_type_w) 37.346 + && (port->type != port_type_k)) 37.347 + || (!elem->v.signal.id.in && (port->type != port_type_input) 37.348 + && (port->type != port_type_output))) 37.349 + { 37.350 + ctx->id = &elem->v.signal.id; 37.351 + return; 37.352 + } 37.353 + 37.354 + free(elem->v.signal.id.id); 37.355 + elem->type = elem_type_signal_port; 37.356 + elem->v.signal.port = port; 37.357 +} 37.358 + 37.359 +struct expr_signal_id * 37.360 +expr_bind_to_ports(expr_t expr, list_t ports) 37.361 +{ 37.362 + struct bind_to_ports_context ctx; 37.363 + 37.364 + ctx.id = NULL; 37.365 + ctx.ports = ports; 37.366 + list_for_each(expr->stack, bind_to_ports, &ctx); 37.367 + 37.368 + return ctx.id; 37.369 +} 37.370 + 37.371 +static int 37.372 +const_v_cmp_id(void *v, void *id) 37.373 +{ 37.374 + return strcmp(((struct const_v *)v)->id, (char *)id); 37.375 +} 37.376 + 37.377 +static void 37.378 +bind_consts_args(void *data, void *context) 37.379 +{ 37.380 + expr_t expr; 37.381 + list_t consts; 37.382 + 37.383 + expr = (expr_t)data; 37.384 + consts = (list_t)context; 37.385 + 37.386 + expr_bind_consts(expr, consts); 37.387 +} 37.388 + 37.389 +static void 37.390 +bind_consts(void *data, void *context) 37.391 +{ 37.392 + struct elem *elem; 37.393 + list_t consts; 37.394 + struct const_v *v; 37.395 + 37.396 + elem = (struct elem *)data; 37.397 + consts = (list_t)context; 37.398 + 37.399 + if ((elem->type == elem_type_signal_id) 37.400 + || (elem->type == elem_type_signal_port) 37.401 + || (elem->type == elem_type_signal_ref)) 37.402 + { 37.403 + if (elem->v.signal.delay != NULL) 37.404 + { 37.405 + expr_bind_consts(elem->v.signal.delay, consts); 37.406 + if (elem->v.signal.delay_max != NULL) 37.407 + expr_bind_consts(elem->v.signal.delay_max, 37.408 + consts); 37.409 + return; 37.410 + } 37.411 + } 37.412 + else if ((elem->type == elem_type_call_id) 37.413 + || (elem->type == elem_type_call_ext_func)) 37.414 + { 37.415 + list_for_each(elem->v.func.args, bind_consts_args, consts); 37.416 + return; 37.417 + } 37.418 + 37.419 + if (elem->type != elem_type_signal_id) 37.420 + return; 37.421 + if (elem->v.signal.id.in) 37.422 + return; 37.423 + 37.424 + v = list_find(consts, const_v_cmp_id, elem->v.signal.id.id); 37.425 + if (v == NULL) 37.426 + return; 37.427 + 37.428 + free(elem->v.signal.id.id); 37.429 + elem->type = elem_type_value; 37.430 + elem->v.value = v->value; 37.431 +} 37.432 + 37.433 +void 37.434 +expr_bind_consts(expr_t expr, list_t consts) 37.435 +{ 37.436 + list_for_each(expr->stack, bind_consts, consts); 37.437 +} 37.438 + 37.439 +static int 37.440 +ext_func_cmp_id(void *f, void *id) 37.441 +{ 37.442 + return strcmp(((struct ext_func *)f)->id, (char *)id); 37.443 +} 37.444 + 37.445 +struct bind_ext_funcs_context 37.446 + { 37.447 + char *ret; 37.448 + list_t funcs; 37.449 + }; 37.450 + 37.451 +static void 37.452 +bind_ext_funcs_args(void *data, void *context) 37.453 +{ 37.454 + expr_t expr; 37.455 + struct bind_ext_funcs_context *ctx; 37.456 + 37.457 + expr = (expr_t)data; 37.458 + ctx = (struct bind_ext_funcs_context *)context; 37.459 + 37.460 + ctx->ret = expr_bind_ext_funcs(expr, ctx->funcs); 37.461 +} 37.462 + 37.463 +static void 37.464 +bind_ext_funcs(void *data, void *context) 37.465 +{ 37.466 + struct elem *elem; 37.467 + struct bind_ext_funcs_context *ctx; 37.468 + struct ext_func *func; 37.469 + 37.470 + elem = (struct elem *)data; 37.471 + ctx = (struct bind_ext_funcs_context *)context; 37.472 + 37.473 + if (ctx->ret != NULL) 37.474 + return; 37.475 + 37.476 + if ((elem->type == elem_type_signal_id) 37.477 + || (elem->type == elem_type_signal_port) 37.478 + || (elem->type == elem_type_signal_ref)) 37.479 + { 37.480 + if (elem->v.signal.delay != NULL) 37.481 + { 37.482 + ctx->ret = expr_bind_ext_funcs(elem->v.signal.delay, 37.483 + ctx->funcs); 37.484 + if (ctx->ret != NULL) 37.485 + return; 37.486 + 37.487 + if (elem->v.signal.delay_max != NULL) 37.488 + ctx->ret = expr_bind_ext_funcs( 37.489 + elem->v.signal.delay_max, ctx->funcs); 37.490 + return; 37.491 + } 37.492 + } 37.493 + else if ((elem->type == elem_type_call_id) 37.494 + || (elem->type == elem_type_call_ext_func)) 37.495 + list_for_each(elem->v.func.args, bind_ext_funcs_args, ctx); 37.496 + 37.497 + if (elem->type != elem_type_call_id) 37.498 + return; 37.499 + 37.500 + func = list_find(ctx->funcs, ext_func_cmp_id, elem->v.func.id); 37.501 + if (func == NULL) 37.502 + { 37.503 + ctx->ret = elem->v.func.id; 37.504 + return; 37.505 + } 37.506 + 37.507 + free(elem->v.func.id); 37.508 + elem->type = elem_type_call_ext_func; 37.509 + elem->v.func.ext_func = func; 37.510 +} 37.511 + 37.512 +char * 37.513 +expr_bind_ext_funcs(expr_t expr, list_t ext_funcs) 37.514 +{ 37.515 + struct bind_ext_funcs_context ctx; 37.516 + 37.517 + ctx.ret = NULL; 37.518 + ctx.funcs = ext_funcs; 37.519 + list_for_each(expr->stack, bind_ext_funcs, &ctx); 37.520 + 37.521 + return ctx.ret; 37.522 +} 37.523 + 37.524 +static void 37.525 +expr_find_unbinded_args(void *data, void *context) 37.526 +{ 37.527 + expr_t expr; 37.528 + struct expr_signal_id **unbinded; 37.529 + 37.530 + expr = (expr_t)data; 37.531 + unbinded = (struct expr_signal_id **)context; 37.532 + 37.533 + if (*unbinded != NULL) 37.534 + return; 37.535 + 37.536 + *unbinded = expr_find_unbinded(expr); 37.537 +} 37.538 + 37.539 +static void 37.540 +elem_is_unbinded(void *data, void *context) 37.541 +{ 37.542 + struct elem *elem; 37.543 + struct expr_signal_id **unbinded; 37.544 + 37.545 + elem = (struct elem *)data; 37.546 + unbinded = (struct expr_signal_id **)context; 37.547 + 37.548 + if (*unbinded != NULL) 37.549 + return; 37.550 + 37.551 + if (elem->type == elem_type_signal_id) 37.552 + *unbinded = &elem->v.signal.id; 37.553 + else if ((elem->type == elem_type_signal_port) 37.554 + || (elem->type == elem_type_signal_ref)) 37.555 + { 37.556 + if (elem->v.signal.delay != NULL) 37.557 + *unbinded = expr_find_unbinded(elem->v.signal.delay); 37.558 + if (*unbinded != NULL) 37.559 + return; 37.560 + if (elem->v.signal.delay_max != NULL) 37.561 + *unbinded = expr_find_unbinded( 37.562 + elem->v.signal.delay_max); 37.563 + } 37.564 + else if ((elem->type == elem_type_call_id) 37.565 + || (elem->type == elem_type_call_ext_func)) 37.566 + list_for_each(elem->v.func.args, expr_find_unbinded_args, 37.567 + unbinded); 37.568 +} 37.569 + 37.570 +struct expr_signal_id * 37.571 +expr_find_unbinded(expr_t expr) 37.572 +{ 37.573 + struct expr_signal_id *ret; 37.574 + 37.575 + ret = NULL; 37.576 + list_for_each(expr->stack, elem_is_unbinded, &ret); 37.577 + 37.578 + return ret; 37.579 +} 37.580 + 37.581 +static void 37.582 +check_ext_func_args(void *data, void *context) 37.583 +{ 37.584 + struct elem *elem; 37.585 + struct ext_func **ret; 37.586 + 37.587 + elem = (struct elem *)data; 37.588 + ret = (struct ext_func **)context; 37.589 + 37.590 + if (*ret != NULL) 37.591 + return; 37.592 + 37.593 + if ((elem->type == elem_type_signal_id) 37.594 + || (elem->type == elem_type_signal_port) 37.595 + || (elem->type == elem_type_signal_ref)) 37.596 + { 37.597 + if (elem->v.signal.delay != NULL) 37.598 + { 37.599 + *ret = expr_check_ext_func_args(elem->v.signal.delay); 37.600 + if (*ret != NULL) 37.601 + return; 37.602 + if (elem->v.signal.delay_max != NULL) 37.603 + *ret = expr_check_ext_func_args( 37.604 + elem->v.signal.delay_max); 37.605 + } 37.606 + } 37.607 + else if (elem->type == elem_type_call_ext_func) 37.608 + { 37.609 + if (list_get_n_elems(elem->v.func.args) 37.610 + != elem->v.func.ext_func->n_args) 37.611 + *ret = elem->v.func.ext_func; 37.612 + } 37.613 +} 37.614 + 37.615 +struct ext_func * 37.616 +expr_check_ext_func_args(expr_t expr) 37.617 +{ 37.618 + struct ext_func *ret; 37.619 + 37.620 + ret = NULL; 37.621 + list_for_each(expr->stack, check_ext_func_args, &ret); 37.622 + 37.623 + return ret; 37.624 +} 37.625 + 37.626 +static int 37.627 +ptr_cmp(void *d1, void *d2) 37.628 +{ 37.629 + return (char *)d1 - (char *)d2; 37.630 +} 37.631 + 37.632 +static void 37.633 +merge_inputs(void *data, void *context) 37.634 +{ 37.635 + struct port *port; 37.636 + list_t list; 37.637 + 37.638 + port = (struct port *)data; 37.639 + list = (list_t)context; 37.640 + 37.641 + if (list_find(list, ptr_cmp, port) != NULL) 37.642 + return; 37.643 + 37.644 + list_append(list, port); 37.645 +} 37.646 + 37.647 +static void 37.648 +merge_inputs_args(void *data, void *context) 37.649 +{ 37.650 + expr_t expr; 37.651 + list_t list; 37.652 + list_t l; 37.653 + 37.654 + expr = (expr_t)data; 37.655 + list = (list_t)context; 37.656 + 37.657 + l = expr_get_inputs(expr); 37.658 + list_for_each(l, merge_inputs, list); 37.659 +} 37.660 + 37.661 +static void 37.662 +add_input(void *data, void *context) 37.663 +{ 37.664 + struct elem *elem; 37.665 + list_t list; 37.666 + list_t l; 37.667 + 37.668 + elem = (struct elem *)data; 37.669 + list = (list_t)context; 37.670 + 37.671 + if (elem->type == elem_type_signal_port) 37.672 + { 37.673 + if (list_find(list, ptr_cmp, elem->v.signal.port) != NULL) 37.674 + return; 37.675 + 37.676 + list_append(list, elem->v.signal.port); 37.677 + 37.678 + if (elem->v.signal.delay != NULL) 37.679 + { 37.680 + l = expr_get_inputs(elem->v.signal.delay); 37.681 + list_for_each(l, merge_inputs, list); 37.682 + } 37.683 + if (elem->v.signal.delay_max != NULL) 37.684 + { 37.685 + l = expr_get_inputs(elem->v.signal.delay_max); 37.686 + list_for_each(l, merge_inputs, list); 37.687 + } 37.688 + } 37.689 + else if (elem->type == elem_type_call_ext_func) 37.690 + list_for_each(elem->v.func.args, merge_inputs_args, list); 37.691 +} 37.692 + 37.693 +list_t 37.694 +expr_get_inputs(expr_t expr) 37.695 +{ 37.696 + list_t ret; 37.697 + 37.698 + ret = list_new(); 37.699 + 37.700 + list_for_each(expr->stack, add_input, ret); 37.701 + 37.702 + return ret; 37.703 +} 37.704 + 37.705 +static void 37.706 +merge_refs(void *data, void *context) 37.707 +{ 37.708 + struct scheduled_expr *ref; 37.709 + list_t list; 37.710 + 37.711 + ref = (struct scheduled_expr *)data; 37.712 + list = (list_t)context; 37.713 + 37.714 + if (list_find(list, ptr_cmp, ref) != NULL) 37.715 + return; 37.716 + 37.717 + list_append(list, ref); 37.718 +} 37.719 + 37.720 +static void 37.721 +merge_refs_args(void *data, void *context) 37.722 +{ 37.723 + expr_t expr; 37.724 + list_t list; 37.725 + list_t l; 37.726 + 37.727 + expr = (expr_t)data; 37.728 + list = (list_t)context; 37.729 + 37.730 + l = expr_get_refs(expr); 37.731 + list_for_each(l, merge_refs, list); 37.732 +} 37.733 + 37.734 +static void 37.735 +add_ref(void *data, void *context) 37.736 +{ 37.737 + struct elem *elem; 37.738 + list_t list; 37.739 + list_t l; 37.740 + 37.741 + elem = (struct elem *)data; 37.742 + list = (list_t)context; 37.743 + 37.744 + if (elem->type == elem_type_signal_ref) 37.745 + { 37.746 + list_append(list, elem->v.signal.ref); 37.747 + 37.748 + if (elem->v.signal.delay != NULL) 37.749 + { 37.750 + l = expr_get_refs(elem->v.signal.delay); 37.751 + list_for_each(l, merge_refs, list); 37.752 + } 37.753 + /*if (elem->v.signal.delay_max != NULL) 37.754 + { 37.755 + l = expr_get_refs(elem->v.signal.delay_max); 37.756 + list_for_each(l, merge_refs, list); 37.757 + }*/ 37.758 + } 37.759 + else if (elem->type == elem_type_call_ext_func) 37.760 + list_for_each(elem->v.func.args, merge_refs_args, list); 37.761 +} 37.762 + 37.763 +list_t 37.764 +expr_get_refs(expr_t expr) 37.765 +{ 37.766 + list_t ret; 37.767 + 37.768 + ret = list_new(); 37.769 + 37.770 + list_for_each(expr->stack, add_ref, ret); 37.771 + 37.772 + return ret; 37.773 +} 37.774 + 37.775 +static void 37.776 +merge_df_refs_args(void *data, void *context) 37.777 +{ 37.778 + expr_t expr; 37.779 + list_t list; 37.780 + list_t l; 37.781 + 37.782 + expr = (expr_t)data; 37.783 + list = (list_t)context; 37.784 + 37.785 + l = expr_get_df_refs(expr); 37.786 + list_for_each(l, merge_refs, list); 37.787 +} 37.788 + 37.789 +static void 37.790 +add_df_ref(void *data, void *context) 37.791 +{ 37.792 + struct elem *elem; 37.793 + list_t list; 37.794 + list_t l; 37.795 + 37.796 + elem = (struct elem *)data; 37.797 + list = (list_t)context; 37.798 + 37.799 + if (elem->type == elem_type_signal_ref) 37.800 + { 37.801 + if (elem->v.signal.delay != NULL) 37.802 + { 37.803 + l = expr_get_df_refs(elem->v.signal.delay); 37.804 + list_for_each(l, merge_refs, list); 37.805 + /*if (elem->v.signal.delay_max != NULL) 37.806 + { 37.807 + l = expr_get_df_refs(elem->v.signal.delay_max); 37.808 + list_for_each(l, merge_refs, list); 37.809 + }*/ 37.810 + } 37.811 + else 37.812 + list_append(list, elem->v.signal.ref); 37.813 + } 37.814 + else if (elem->type == elem_type_call_ext_func) 37.815 + list_for_each(elem->v.func.args, merge_df_refs_args, list); 37.816 +} 37.817 + 37.818 +list_t 37.819 +expr_get_df_refs(expr_t expr) 37.820 +{ 37.821 + list_t ret; 37.822 + 37.823 + ret = list_new(); 37.824 + 37.825 + list_for_each(expr->stack, add_df_ref, ret); 37.826 + 37.827 + return ret; 37.828 +} 37.829 + 37.830 +struct add_delay_context 37.831 + { 37.832 + list_t list; 37.833 + struct scheduled_expr *ref; 37.834 + }; 37.835 + 37.836 +static void 37.837 +add_delay_args(void *data, void *context) 37.838 +{ 37.839 + expr_t expr; 37.840 + struct add_delay_context *ctx; 37.841 + 37.842 + expr = (expr_t)data; 37.843 + ctx = (struct add_delay_context *)context; 37.844 + 37.845 + list_merge(ctx->list, expr_get_delays(expr, ctx->ref)); 37.846 +} 37.847 + 37.848 +static void 37.849 +add_delay(void *data, void *context) 37.850 +{ 37.851 + struct elem *elem; 37.852 + struct add_delay_context *ctx; 37.853 + struct delay *d; 37.854 + 37.855 + elem = (struct elem *)data; 37.856 + ctx = (struct add_delay_context *)context; 37.857 + 37.858 + if (elem->type == elem_type_signal_ref) 37.859 + { 37.860 + if (elem->v.signal.ref == ctx->ref) 37.861 + { 37.862 + if (elem->v.signal.delay != NULL) 37.863 + { 37.864 + d = xmalloc(sizeof(struct delay)); 37.865 + d->delay = elem->v.signal.delay; 37.866 + d->delay_max = elem->v.signal.delay_max; 37.867 + list_append(ctx->list, d); 37.868 + } 37.869 + } 37.870 + else if (elem->v.signal.delay != NULL) 37.871 + list_merge(ctx->list, 37.872 + expr_get_delays(elem->v.signal.delay, 37.873 + ctx->ref)); 37.874 + } 37.875 + else if (elem->type == elem_type_call_ext_func) 37.876 + list_for_each(elem->v.func.args, add_delay_args, ctx); 37.877 +} 37.878 + 37.879 +list_t 37.880 +expr_get_delays(expr_t expr, struct scheduled_expr *ref) 37.881 +{ 37.882 + struct add_delay_context ctx; 37.883 + 37.884 + ctx.list = list_new(); 37.885 + ctx.ref = ref; 37.886 + list_for_each(expr->stack, add_delay, &ctx); 37.887 + 37.888 + return ctx.list; 37.889 +} 37.890 + 37.891 +static void 37.892 +merge_ext_funcs(void *data, void *context) 37.893 +{ 37.894 + struct ext_func *func; 37.895 + list_t list; 37.896 + 37.897 + func = (struct ext_func *)data; 37.898 + list = (list_t)context; 37.899 + 37.900 + if (list_find(list, ptr_cmp, func) == NULL) 37.901 + list_append(list, func); 37.902 +} 37.903 + 37.904 +static void 37.905 +merge_ext_funcs_args(void *data, void *context) 37.906 +{ 37.907 + expr_t expr; 37.908 + list_t list; 37.909 + list_t l; 37.910 + 37.911 + expr = (expr_t)data; 37.912 + list = (list_t)context; 37.913 + 37.914 + l = expr_get_ext_funcs(expr); 37.915 + list_for_each(l, merge_ext_funcs, list); 37.916 +} 37.917 + 37.918 +static void 37.919 +add_ext_func(void *data, void *context) 37.920 +{ 37.921 + struct elem *elem; 37.922 + list_t list; 37.923 + list_t l; 37.924 + 37.925 + elem = (struct elem *)data; 37.926 + list = (list_t)context; 37.927 + 37.928 + if (elem->type == elem_type_signal_ref) 37.929 + { 37.930 + if (elem->v.signal.delay != NULL) 37.931 + { 37.932 + l = expr_get_ext_funcs(elem->v.signal.delay); 37.933 + list_for_each(l, merge_ext_funcs, list); 37.934 + } 37.935 + if (elem->v.signal.delay_max != NULL) 37.936 + { 37.937 + l = expr_get_ext_funcs(elem->v.signal.delay_max); 37.938 + list_for_each(l, merge_ext_funcs, list); 37.939 + } 37.940 + } 37.941 + else if (elem->type == elem_type_call_ext_func) 37.942 + { 37.943 + if (list_find(list, ptr_cmp, elem->v.func.ext_func) == NULL) 37.944 + list_append(list, elem->v.func.ext_func); 37.945 + list_for_each(elem->v.func.args, merge_ext_funcs_args, list); 37.946 + } 37.947 +} 37.948 + 37.949 +list_t 37.950 +expr_get_ext_funcs(expr_t expr) 37.951 +{ 37.952 + list_t ret; 37.953 + 37.954 + ret = list_new(); 37.955 + list_for_each(expr->stack, add_ext_func, ret); 37.956 + 37.957 + return ret; 37.958 +} 37.959 + 37.960 +static void 37.961 +arg_copy(void *data, void *context) 37.962 +{ 37.963 + expr_t expr; 37.964 + list_t list; 37.965 + 37.966 + expr = (expr_t)data; 37.967 + list = (list_t)context; 37.968 + 37.969 + list_append(list, expr_copy(expr)); 37.970 +} 37.971 + 37.972 +static void 37.973 +elem_copy(void *data, void *context) 37.974 +{ 37.975 + struct elem *elem, *e; 37.976 + list_t stack; 37.977 + 37.978 + elem = (struct elem *)data; 37.979 + stack = (list_t)context; 37.980 + 37.981 + e = xmalloc(sizeof(struct elem)); 37.982 + *e = *elem; 37.983 + 37.984 + if (elem->type == elem_type_signal_id) 37.985 + e->v.signal.id.id = copy_str(elem->v.signal.id.id); 37.986 + else if (elem->type == elem_type_call_id) 37.987 + e->v.func.id = copy_str(elem->v.func.id); 37.988 + 37.989 + if ((elem->type == elem_type_signal_id) 37.990 + || (elem->type == elem_type_signal_port) 37.991 + || (elem->type == elem_type_signal_ref)) 37.992 + { 37.993 + if (elem->v.signal.delay != NULL) 37.994 + e->v.signal.delay = expr_copy(elem->v.signal.delay); 37.995 + else 37.996 + e->v.signal.delay = NULL; 37.997 + 37.998 + if (elem->v.signal.delay_max != NULL) 37.999 + e->v.signal.delay_max = 37.1000 + expr_copy(elem->v.signal.delay_max); 37.1001 + else 37.1002 + e->v.signal.delay_max = NULL; 37.1003 + } 37.1004 + else if ((elem->type == elem_type_call_id) 37.1005 + || (elem->type == elem_type_call_ext_func)) 37.1006 + { 37.1007 + e->v.func.args = list_new(); 37.1008 + list_for_each(elem->v.func.args, arg_copy, e->v.func.args); 37.1009 + } 37.1010 + 37.1011 + list_append(stack, e); 37.1012 +} 37.1013 + 37.1014 +expr_t 37.1015 +expr_copy(expr_t expr) 37.1016 +{ 37.1017 + struct _expr *ret; 37.1018 + 37.1019 + ret = xmalloc(sizeof(struct _expr)); 37.1020 + ret->stack = list_new(); 37.1021 + 37.1022 + list_for_each(expr->stack, elem_copy, ret->stack); 37.1023 + 37.1024 + return ret; 37.1025 +} 37.1026 + 37.1027 +struct port_to_value_context 37.1028 + { 37.1029 + struct port *port; 37.1030 + double value; 37.1031 + }; 37.1032 + 37.1033 +static void 37.1034 +port_to_value_args(void *data, void *context) 37.1035 +{ 37.1036 + expr_t expr; 37.1037 + struct port_to_value_context *ctx; 37.1038 + 37.1039 + expr = (expr_t)data; 37.1040 + ctx = (struct port_to_value_context *)context; 37.1041 + 37.1042 + expr_port_to_value(expr, ctx->port, ctx->value); 37.1043 +} 37.1044 + 37.1045 +static void 37.1046 +port_to_value(void *data, void *context) 37.1047 +{ 37.1048 + struct elem *elem; 37.1049 + struct port_to_value_context *ctx; 37.1050 + 37.1051 + elem = (struct elem *)data; 37.1052 + ctx = (struct port_to_value_context *)context; 37.1053 + 37.1054 + if ((elem->type == elem_type_signal_id) 37.1055 + || (elem->type == elem_type_signal_port) 37.1056 + || (elem->type == elem_type_signal_ref)) 37.1057 + { 37.1058 + if (elem->v.signal.delay != NULL) 37.1059 + expr_port_to_value(elem->v.signal.delay, ctx->port, 37.1060 + ctx->value); 37.1061 + if (elem->v.signal.delay_max != NULL) 37.1062 + expr_port_to_value(elem->v.signal.delay_max, ctx->port, 37.1063 + ctx->value); 37.1064 + } 37.1065 + else if ((elem->type == elem_type_call_id) 37.1066 + || (elem->type == elem_type_call_ext_func)) 37.1067 + list_for_each(elem->v.func.args, port_to_value_args, ctx); 37.1068 + 37.1069 + if (elem->type == elem_type_signal_port) 37.1070 + { 37.1071 + if (elem->v.signal.port != ctx->port) 37.1072 + return; 37.1073 + 37.1074 + if (elem->v.signal.delay != NULL) 37.1075 + expr_free(elem->v.signal.delay); 37.1076 + if (elem->v.signal.delay_max != NULL) 37.1077 + expr_free(elem->v.signal.delay_max); 37.1078 + 37.1079 + elem->type = elem_type_value; 37.1080 + elem->v.value = ctx->value; 37.1081 + } 37.1082 +} 37.1083 + 37.1084 +void 37.1085 +expr_port_to_value(expr_t expr, struct port *port, double value) 37.1086 +{ 37.1087 + struct port_to_value_context ctx; 37.1088 + 37.1089 + ctx.port = port; 37.1090 + ctx.value = value; 37.1091 + list_for_each(expr->stack, port_to_value, &ctx); 37.1092 +} 37.1093 + 37.1094 +struct port_to_ref_context 37.1095 + { 37.1096 + struct port *port; 37.1097 + struct scheduled_expr *ref; 37.1098 + }; 37.1099 + 37.1100 +static void 37.1101 +port_to_ref_args(void *data, void *context) 37.1102 +{ 37.1103 + expr_t expr; 37.1104 + struct port_to_ref_context *ctx; 37.1105 + 37.1106 + expr = (expr_t)data; 37.1107 + ctx = (struct port_to_ref_context *)context; 37.1108 + 37.1109 + expr_port_to_ref(expr, ctx->port, ctx->ref); 37.1110 +} 37.1111 + 37.1112 +static void 37.1113 +port_to_ref(void *data, void *context) 37.1114 +{ 37.1115 + struct elem *elem; 37.1116 + struct port_to_ref_context *ctx; 37.1117 + 37.1118 + elem = (struct elem *)data; 37.1119 + ctx = (struct port_to_ref_context *)context; 37.1120 + 37.1121 + if ((elem->type == elem_type_signal_id) 37.1122 + || (elem->type == elem_type_signal_port) 37.1123 + || (elem->type == elem_type_signal_ref)) 37.1124 + { 37.1125 + if (elem->v.signal.delay != NULL) 37.1126 + expr_port_to_ref(elem->v.signal.delay, ctx->port, 37.1127 + ctx->ref); 37.1128 + if (elem->v.signal.delay_max != NULL) 37.1129 + expr_port_to_ref(elem->v.signal.delay_max, ctx->port, 37.1130 + ctx->ref); 37.1131 + } 37.1132 + else if ((elem->type == elem_type_call_id) 37.1133 + || (elem->type == elem_type_call_ext_func)) 37.1134 + list_for_each(elem->v.func.args, port_to_ref_args, ctx); 37.1135 + 37.1136 + if (elem->type == elem_type_signal_port) 37.1137 + { 37.1138 + if (elem->v.signal.port != ctx->port) 37.1139 + return; 37.1140 + 37.1141 + elem->type = elem_type_signal_ref; 37.1142 + elem->v.signal.ref = ctx->ref; 37.1143 + } 37.1144 +} 37.1145 + 37.1146 +void 37.1147 +expr_port_to_ref(expr_t expr, struct port *port, struct scheduled_expr *ref) 37.1148 +{ 37.1149 + struct port_to_ref_context ctx; 37.1150 + 37.1151 + ctx.port = port; 37.1152 + ctx.ref = ref; 37.1153 + list_for_each(expr->stack, port_to_ref, &ctx); 37.1154 +} 37.1155 + 37.1156 +static void 37.1157 +arg_contains_ref(void *data, void *context) 37.1158 +{ 37.1159 + expr_t expr; 37.1160 + char *found; 37.1161 + 37.1162 + expr = (expr_t)data; 37.1163 + found = (char *)context; 37.1164 + 37.1165 + if (*found) 37.1166 + return; 37.1167 + 37.1168 + *found = expr_contains_ref(expr); 37.1169 +} 37.1170 + 37.1171 +static void 37.1172 +contains_ref(void *data, void *context) 37.1173 +{ 37.1174 + struct elem *elem; 37.1175 + char *found; 37.1176 + 37.1177 + elem = (struct elem *)data; 37.1178 + found = (char *)context; 37.1179 + 37.1180 + if (*found) 37.1181 + return; 37.1182 + 37.1183 + if (elem->type == elem_type_signal_ref) 37.1184 + *found = 1; 37.1185 + else if ((elem->type == elem_type_call_id) 37.1186 + || (elem->type == elem_type_call_ext_func)) 37.1187 + list_for_each(elem->v.func.args, arg_contains_ref, found); 37.1188 +} 37.1189 + 37.1190 +char 37.1191 +expr_contains_ref(expr_t expr) 37.1192 +{ 37.1193 + char ref_found; 37.1194 + 37.1195 + ref_found = 0; 37.1196 + list_for_each(expr->stack, contains_ref, &ref_found); 37.1197 + 37.1198 + return ref_found; 37.1199 +} 37.1200 + 37.1201 +static void 37.1202 +arg_contains_sample_rate(void *data, void *context) 37.1203 +{ 37.1204 + expr_t expr; 37.1205 + char *found; 37.1206 + 37.1207 + expr = (expr_t)data; 37.1208 + found = (char *)context; 37.1209 + 37.1210 + if (*found) 37.1211 + return; 37.1212 + 37.1213 + *found = expr_contains_sample_rate(expr); 37.1214 +} 37.1215 + 37.1216 +static void 37.1217 +contains_sample_rate(void *data, void *context) 37.1218 +{ 37.1219 + struct elem *elem; 37.1220 + char *found; 37.1221 + 37.1222 + elem = (struct elem *)data; 37.1223 + found = (char *)context; 37.1224 + 37.1225 + if (*found) 37.1226 + return; 37.1227 + 37.1228 + if (elem->type == elem_type_signal_ref) 37.1229 + { 37.1230 + if (elem->v.signal.delay != NULL) 37.1231 + *found = expr_contains_sample_rate( 37.1232 + elem->v.signal.delay); 37.1233 + if (*found) 37.1234 + return; 37.1235 + 37.1236 + if (elem->v.signal.delay_max != NULL) 37.1237 + *found = expr_contains_sample_rate( 37.1238 + elem->v.signal.delay_max); 37.1239 + } 37.1240 + else if (elem->type == elem_type_sample_rate) 37.1241 + *found = 1; 37.1242 + else if ((elem->type == elem_type_call_id) 37.1243 + || (elem->type == elem_type_call_ext_func)) 37.1244 + list_for_each(elem->v.func.args, arg_contains_sample_rate, 37.1245 + found); 37.1246 +} 37.1247 + 37.1248 +char 37.1249 +expr_contains_sample_rate(expr_t expr) 37.1250 +{ 37.1251 + char sr_found; 37.1252 + 37.1253 + sr_found = 0; 37.1254 + list_for_each(expr->stack, contains_sample_rate, &sr_found); 37.1255 + 37.1256 + return sr_found; 37.1257 +} 37.1258 + 37.1259 +struct is_const_context 37.1260 + { 37.1261 + list_t stack; 37.1262 + char ret; 37.1263 + }; 37.1264 + 37.1265 +static void 37.1266 +is_const(void *data, void *context) 37.1267 +{ 37.1268 + struct elem *elem; 37.1269 + struct is_const_context *ctx; 37.1270 + 37.1271 + elem = (struct elem *)data; 37.1272 + ctx = (struct is_const_context *)context; 37.1273 + 37.1274 + if (!ctx->ret) 37.1275 + return; 37.1276 + 37.1277 + if ((elem->type == elem_type_sample_rate) 37.1278 + || (elem->type == elem_type_call_ext_func)) 37.1279 + { 37.1280 + ctx->ret = 0; 37.1281 + return; 37.1282 + } 37.1283 + 37.1284 + if (elem->type == elem_type_signal_ref) 37.1285 + { 37.1286 + if (elem->v.signal.ref->component == NULL) 37.1287 + { 37.1288 + ctx->ret = 0; 37.1289 + return; 37.1290 + } 37.1291 + 37.1292 + if (list_find(ctx->stack, ptr_cmp, elem->v.signal.ref->expr) 37.1293 + != NULL) 37.1294 + { 37.1295 + ctx->ret = 0; 37.1296 + return; 37.1297 + } 37.1298 + 37.1299 + list_push(ctx->stack, elem->v.signal.ref->expr); 37.1300 + list_for_each(elem->v.signal.ref->expr->stack, is_const, ctx); 37.1301 + list_pop(ctx->stack); 37.1302 + } 37.1303 +} 37.1304 + 37.1305 +char 37.1306 +expr_is_const(expr_t expr) 37.1307 +{ 37.1308 + struct is_const_context ctx; 37.1309 + 37.1310 + ctx.ret = 1; 37.1311 + ctx.stack = list_new(); 37.1312 + list_push(ctx.stack, expr); 37.1313 + list_for_each(expr->stack, is_const, &ctx); 37.1314 + list_free(ctx.stack); 37.1315 + 37.1316 + return ctx.ret; 37.1317 +} 37.1318 + 37.1319 +static void is_rt_const(void *data, void *context); 37.1320 + 37.1321 +static void 37.1322 +arg_is_rt_const(void *data, void *context) 37.1323 +{ 37.1324 + expr_t expr; 37.1325 + struct is_const_context *ctx; 37.1326 + 37.1327 + expr = (expr_t)data; 37.1328 + ctx = (struct is_const_context *)context; 37.1329 + 37.1330 + if (!ctx->ret) 37.1331 + return; 37.1332 + 37.1333 + list_push(ctx->stack, expr); 37.1334 + list_for_each(expr->stack, is_rt_const, ctx); 37.1335 + list_pop(ctx->stack); 37.1336 +} 37.1337 + 37.1338 +static void 37.1339 +is_rt_const(void *data, void *context) 37.1340 +{ 37.1341 + struct elem *elem; 37.1342 + struct is_const_context *ctx; 37.1343 + 37.1344 + elem = (struct elem *)data; 37.1345 + ctx = (struct is_const_context *)context; 37.1346 + 37.1347 + if (!ctx->ret) 37.1348 + return; 37.1349 + 37.1350 + if (elem->type == elem_type_signal_ref) 37.1351 + { 37.1352 + if (elem->v.signal.ref->component == NULL) 37.1353 + { 37.1354 + ctx->ret = 0; 37.1355 + return; 37.1356 + } 37.1357 + 37.1358 + if (list_find(ctx->stack, ptr_cmp, elem->v.signal.ref->expr) 37.1359 + != NULL) 37.1360 + { 37.1361 + ctx->ret = 0; 37.1362 + return; 37.1363 + } 37.1364 + 37.1365 + list_push(ctx->stack, elem->v.signal.ref->expr); 37.1366 + list_for_each(elem->v.signal.ref->expr->stack, is_rt_const, 37.1367 + ctx); 37.1368 + list_pop(ctx->stack); 37.1369 + } 37.1370 + else if (elem->type == elem_type_call_ext_func) 37.1371 + list_for_each(elem->v.func.args, arg_is_rt_const, ctx); 37.1372 +} 37.1373 + 37.1374 +char 37.1375 +expr_is_rt_const(expr_t expr) 37.1376 +{ 37.1377 + struct is_const_context ctx; 37.1378 + 37.1379 + ctx.ret = 1; 37.1380 + ctx.stack = list_new(); 37.1381 + list_push(ctx.stack, expr); 37.1382 + list_for_each(expr->stack, is_rt_const, &ctx); 37.1383 + list_free(ctx.stack); 37.1384 + 37.1385 + return ctx.ret; 37.1386 +} 37.1387 + 37.1388 +static double 37.1389 +eval(expr_t expr) 37.1390 +{ 37.1391 + struct elem *elem; 37.1392 + double val; 37.1393 + 37.1394 + elem = list_pop(expr->stack); 37.1395 + 37.1396 + switch(elem->type) 37.1397 + { 37.1398 + case elem_type_value: 37.1399 + val = elem->v.value; 37.1400 + break; 37.1401 + case elem_type_add: 37.1402 + val = eval(expr); 37.1403 + val += eval(expr); 37.1404 + break; 37.1405 + case elem_type_sub: 37.1406 + val = eval(expr); 37.1407 + val -= eval(expr); 37.1408 + break; 37.1409 + case elem_type_mul: 37.1410 + val = eval(expr); 37.1411 + val *= eval(expr); 37.1412 + break; 37.1413 + case elem_type_div: 37.1414 + val = eval(expr); 37.1415 + val /= eval(expr); 37.1416 + break; 37.1417 + case elem_type_plus: 37.1418 + val = eval(expr); 37.1419 + break; 37.1420 + case elem_type_minus: 37.1421 + val = -eval(expr); 37.1422 + break; 37.1423 + case elem_type_signal_ref: 37.1424 + val = expr_eval(elem->v.signal.ref->expr); 37.1425 + break; 37.1426 + default: 37.1427 + /* this should never happen */ 37.1428 + fprintf(stderr, "error: oops in eval()\n"); 37.1429 + list_push(expr->stack, elem); 37.1430 + expr_dump(expr); 37.1431 + exit(EXIT_FAILURE); 37.1432 + break; 37.1433 + } 37.1434 + 37.1435 + return val; 37.1436 +} 37.1437 + 37.1438 +double 37.1439 +expr_eval(expr_t expr) 37.1440 +{ 37.1441 + expr_t eval_expr; 37.1442 + double val; 37.1443 + 37.1444 + eval_expr = expr_copy(expr); 37.1445 + 37.1446 + val = eval(eval_expr); 37.1447 + 37.1448 + expr_free(eval_expr); 37.1449 + 37.1450 + return val; 37.1451 +} 37.1452 + 37.1453 +static void 37.1454 +expr_free_args(void *data, void *context) 37.1455 +{ 37.1456 + expr_free((expr_t)data); 37.1457 +} 37.1458 + 37.1459 +static void 37.1460 +free_elem(void *data, void *context) 37.1461 +{ 37.1462 + struct elem *elem; 37.1463 + 37.1464 + elem = (struct elem *)data; 37.1465 + 37.1466 + if (elem->type == elem_type_signal_id) 37.1467 + free(elem->v.signal.id.id); 37.1468 + else if (elem->type == elem_type_call_id) 37.1469 + free(elem->v.func.id); 37.1470 + 37.1471 + if ((elem->type == elem_type_signal_id) 37.1472 + || (elem->type == elem_type_signal_port) 37.1473 + || (elem->type == elem_type_signal_ref)) 37.1474 + { 37.1475 + if (elem->v.signal.delay != NULL) 37.1476 + expr_free(elem->v.signal.delay); 37.1477 + if (elem->v.signal.delay_max != NULL) 37.1478 + expr_free(elem->v.signal.delay_max); 37.1479 + } 37.1480 + else if ((elem->type == elem_type_call_id) 37.1481 + || (elem->type == elem_type_call_ext_func)) 37.1482 + { 37.1483 + list_for_each(elem->v.func.args, expr_free_args, NULL); 37.1484 + list_free(elem->v.func.args); 37.1485 + } 37.1486 + 37.1487 + free(elem); 37.1488 +} 37.1489 + 37.1490 +void 37.1491 +expr_free(expr_t expr) 37.1492 +{ 37.1493 + list_for_each(expr->stack, free_elem, NULL); 37.1494 + list_free(expr->stack); 37.1495 + free(expr); 37.1496 +} 37.1497 + 37.1498 +static void 37.1499 +arg_dump(void *data, void *context) 37.1500 +{ 37.1501 + expr_t expr; 37.1502 + char *first; 37.1503 + 37.1504 + expr = (expr_t)data; 37.1505 + first = (char *)context; 37.1506 + 37.1507 + if (*first) 37.1508 + *first = 0; 37.1509 + else 37.1510 + printf(", "); 37.1511 + 37.1512 + expr_dump(expr); 37.1513 +} 37.1514 + 37.1515 +static void 37.1516 +elem_dump(list_t stack) 37.1517 +{ 37.1518 + struct elem *e; 37.1519 + char first; 37.1520 + 37.1521 + e = list_pop(stack); 37.1522 + 37.1523 + switch (e->type) 37.1524 + { 37.1525 + case elem_type_value: 37.1526 + printf("%.*f", DBL_DIG, e->v.value); 37.1527 + break; 37.1528 + case elem_type_sample_rate: 37.1529 + printf("sample_rate"); 37.1530 + break; 37.1531 + case elem_type_signal_ref: 37.1532 + printf("%s%s%s%s", 37.1533 + (e->v.signal.ref->component != NULL) 37.1534 + ? e->v.signal.ref->component->id : "", 37.1535 + (e->v.signal.ref->component != NULL) ? "." : "", 37.1536 + e->v.signal.ref->port->id, 37.1537 + ((e->v.signal.ref->port->type == port_type_w) 37.1538 + || (e->v.signal.ref->port->type == port_type_k)) 37.1539 + ? ".in" : ""); 37.1540 + if (e->v.signal.delay != NULL) 37.1541 + { 37.1542 + printf("["); 37.1543 + expr_dump(e->v.signal.delay); 37.1544 + if (e->v.signal.delay_max != NULL) 37.1545 + { 37.1546 + printf(", "); 37.1547 + expr_dump(e->v.signal.delay_max); 37.1548 + } 37.1549 + printf("]"); 37.1550 + } 37.1551 + break; 37.1552 + case elem_type_call_ext_func: 37.1553 + printf("%s(", e->v.func.ext_func->id); 37.1554 + first = 1; 37.1555 + list_for_each(e->v.func.args, arg_dump, &first); 37.1556 + printf(")"); 37.1557 + break; 37.1558 + case elem_type_add: 37.1559 + printf("("); 37.1560 + elem_dump(stack); 37.1561 + printf(") + ("); 37.1562 + elem_dump(stack); 37.1563 + printf(")"); 37.1564 + break; 37.1565 + case elem_type_sub: 37.1566 + printf("("); 37.1567 + elem_dump(stack); 37.1568 + printf(") - ("); 37.1569 + elem_dump(stack); 37.1570 + printf(")"); 37.1571 + break; 37.1572 + case elem_type_mul: 37.1573 + printf("("); 37.1574 + elem_dump(stack); 37.1575 + printf(") * ("); 37.1576 + elem_dump(stack); 37.1577 + printf(")"); 37.1578 + break; 37.1579 + case elem_type_div: 37.1580 + printf("("); 37.1581 + elem_dump(stack); 37.1582 + printf(") / ("); 37.1583 + elem_dump(stack); 37.1584 + printf(")"); 37.1585 + break; 37.1586 + case elem_type_plus: 37.1587 + printf("+("); 37.1588 + elem_dump(stack); 37.1589 + printf(")"); 37.1590 + break; 37.1591 + case elem_type_minus: 37.1592 + printf("-("); 37.1593 + elem_dump(stack); 37.1594 + printf(")"); 37.1595 + break; 37.1596 + default: 37.1597 + printf("NOOOOOO %d (%d)!", e->type, elem_type_value); 37.1598 + break; 37.1599 + } 37.1600 +} 37.1601 + 37.1602 +void 37.1603 +expr_dump(expr_t expr) 37.1604 +{ 37.1605 + expr_t expr2; 37.1606 + 37.1607 + expr2 = expr_copy(expr); 37.1608 + 37.1609 + elem_dump(expr2->stack); 37.1610 + 37.1611 + expr_free(expr2); 37.1612 +} 37.1613 + 37.1614 +struct arg_c_compile_context 37.1615 + { 37.1616 + FILE *fp; 37.1617 + char first; 37.1618 + char inside_run; 37.1619 + }; 37.1620 + 37.1621 +static void 37.1622 +arg_c_compile(void *data, void *context) 37.1623 +{ 37.1624 + expr_t expr; 37.1625 + struct arg_c_compile_context *ctx; 37.1626 + 37.1627 + expr = (expr_t)data; 37.1628 + ctx = (struct arg_c_compile_context *)context; 37.1629 + 37.1630 + if (ctx->first) 37.1631 + ctx->first = 0; 37.1632 + else 37.1633 + fprintf(ctx->fp, ", "); 37.1634 + 37.1635 + expr_c_compile(expr, ctx->fp, ctx->inside_run); 37.1636 + expr_free(expr); 37.1637 +} 37.1638 + 37.1639 +static void 37.1640 +elem_c_compile(list_t stack, FILE *fp, char inside_run) 37.1641 +{ 37.1642 + struct elem *e; 37.1643 + struct arg_c_compile_context ctx; 37.1644 + 37.1645 + e = list_pop(stack); 37.1646 + 37.1647 + switch (e->type) 37.1648 + { 37.1649 + case elem_type_value: 37.1650 + fprintf(fp, "%.*f", DBL_DIG, e->v.value); 37.1651 + break; 37.1652 + case elem_type_sample_rate: 37.1653 + fprintf(fp, "%ssample_rate", 37.1654 + inside_run ? "plugin->" : ""); 37.1655 + break; 37.1656 + case elem_type_signal_ref: 37.1657 + if (!inside_run) 37.1658 + { 37.1659 + expr_c_compile(e->v.signal.ref->expr, fp, 0); 37.1660 + if (e->v.signal.delay != NULL) 37.1661 + expr_free(e->v.signal.delay); 37.1662 + if (e->v.signal.delay_max != NULL) 37.1663 + expr_free(e->v.signal.delay_max); 37.1664 + break; 37.1665 + } 37.1666 + 37.1667 + if (e->v.signal.delay == NULL) 37.1668 + { 37.1669 + if (e->v.signal.ref->component == NULL) 37.1670 + fprintf(fp, "plugin->port_%s%s", 37.1671 + e->v.signal.ref->port->id, 37.1672 + (e->v.signal.ref->port->sync 37.1673 + == port_sync_sync) 37.1674 + ? "[i]" : "[0]"); 37.1675 + else 37.1676 + fprintf(fp, "plugin->val_%lu", 37.1677 + e->v.signal.ref->index); 37.1678 + } 37.1679 + else if (e->v.signal.ref->db_type 37.1680 + == delay_buf_type_single) 37.1681 + { 37.1682 + fprintf(fp, "plugin->buf_%lu", 37.1683 + e->v.signal.ref->index); 37.1684 + expr_free(e->v.signal.delay); 37.1685 + if (e->v.signal.delay_max != NULL) 37.1686 + expr_free(e->v.signal.delay_max); 37.1687 + } 37.1688 + else if (e->v.signal.ref->db_type 37.1689 + == delay_buf_type_fixed) 37.1690 + { 37.1691 + fprintf(fp, "plugin->buf_%lu[pmf_delay(", 37.1692 + e->v.signal.ref->index); 37.1693 + expr_c_compile(e->v.signal.delay, fp, 37.1694 + inside_run); 37.1695 + fprintf(fp, ", plugin->buf_%lu_cur, %lu)]", 37.1696 + e->v.signal.ref->index, 37.1697 + (size_t)e->v.signal.ref->delay_min); 37.1698 + expr_free(e->v.signal.delay); 37.1699 + if (e->v.signal.delay_max != NULL) 37.1700 + expr_free(e->v.signal.delay_max); 37.1701 + } 37.1702 + else 37.1703 + { 37.1704 + fprintf(fp, "plugin->buf_%lu[pmf_delay(", 37.1705 + e->v.signal.ref->index); 37.1706 + expr_c_compile(e->v.signal.delay, fp, 37.1707 + inside_run); 37.1708 + fprintf(fp, ", plugin->buf_%lu_cur, " 37.1709 + "plugin->buf_%lu_len - 1)]", 37.1710 + e->v.signal.ref->index, 37.1711 + e->v.signal.ref->index); 37.1712 + expr_free(e->v.signal.delay); 37.1713 + if (e->v.signal.delay_max != NULL) 37.1714 + expr_free(e->v.signal.delay_max); 37.1715 + } 37.1716 + break; 37.1717 + case elem_type_call_ext_func: 37.1718 + fprintf(fp, "%s(", e->v.func.ext_func->f_id); 37.1719 + ctx.fp = fp; 37.1720 + ctx.first = 1; 37.1721 + ctx.inside_run = inside_run; 37.1722 + list_for_each(e->v.func.args, arg_c_compile, &ctx); 37.1723 + list_free(e->v.func.args); 37.1724 + fprintf(fp, ")"); 37.1725 + break; 37.1726 + case elem_type_add: 37.1727 + fprintf(fp, "("); 37.1728 + elem_c_compile(stack, fp, inside_run); 37.1729 + fprintf(fp, ") + ("); 37.1730 + elem_c_compile(stack, fp, inside_run); 37.1731 + fprintf(fp, ")"); 37.1732 + break; 37.1733 + case elem_type_sub: 37.1734 + fprintf(fp, "("); 37.1735 + elem_c_compile(stack, fp, inside_run); 37.1736 + fprintf(fp, ") - ("); 37.1737 + elem_c_compile(stack, fp, inside_run); 37.1738 + fprintf(fp, ")"); 37.1739 + break; 37.1740 + case elem_type_mul: 37.1741 + fprintf(fp, "("); 37.1742 + elem_c_compile(stack, fp, inside_run); 37.1743 + fprintf(fp, ") * ("); 37.1744 + elem_c_compile(stack, fp, inside_run); 37.1745 + fprintf(fp, ")"); 37.1746 + break; 37.1747 + case elem_type_div: 37.1748 + fprintf(fp, "("); 37.1749 + elem_c_compile(stack, fp, inside_run); 37.1750 + fprintf(fp, ") / ("); 37.1751 + elem_c_compile(stack, fp, inside_run); 37.1752 + fprintf(fp, ")"); 37.1753 + break; 37.1754 + case elem_type_plus: 37.1755 + fprintf(fp, "+("); 37.1756 + elem_c_compile(stack, fp, inside_run); 37.1757 + fprintf(fp, ")"); 37.1758 + break; 37.1759 + case elem_type_minus: 37.1760 + fprintf(fp, "-("); 37.1761 + elem_c_compile(stack, fp, inside_run); 37.1762 + fprintf(fp, ")"); 37.1763 + break; 37.1764 + default: 37.1765 + break; 37.1766 + } 37.1767 + 37.1768 + free(e); 37.1769 +} 37.1770 + 37.1771 +void 37.1772 +expr_c_compile(expr_t expr, FILE *fp, char inside_run) 37.1773 +{ 37.1774 + expr_t expr2; 37.1775 + 37.1776 + expr2 = expr_copy(expr); 37.1777 + 37.1778 + elem_c_compile(expr2->stack, fp, inside_run); 37.1779 + 37.1780 + expr_free(expr2); 37.1781 +}
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/permafrost/src/expr.h Sun May 02 14:19:58 2010 +0300 38.3 @@ -0,0 +1,119 @@ 38.4 +/* 38.5 + * Permafrost - Physical modelling framework 38.6 + * 38.7 + * Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 38.8 + * 38.9 + * See the COPYING file for license conditions. 38.10 + */ 38.11 + 38.12 +#ifndef _EXPR_H_ 38.13 +#define _EXPR_H_ 38.14 + 38.15 +#include "src/types.h" 38.16 + 38.17 +expr_t 38.18 +expr_new_value(double value); 38.19 + 38.20 +expr_t 38.21 +expr_new_sample_rate(); 38.22 + 38.23 +expr_t 38.24 +expr_new_signal(char *id, char in, expr_t delay, expr_t delay_max); 38.25 + 38.26 +expr_t 38.27 +expr_new_signal_ref(struct scheduled_expr *ref, expr_t delay, expr_t delay_max); 38.28 + 38.29 +expr_t 38.30 +expr_new_call(char *id, list_t args); 38.31 + 38.32 +/* expr + expr2 */ 38.33 +void 38.34 +expr_push_add(expr_t expr, expr_t expr2); 38.35 + 38.36 +/* expr - expr2 */ 38.37 +void 38.38 +expr_push_sub(expr_t expr, expr_t expr2); 38.39 + 38.40 +/* expr * expr2 */ 38.41 +void 38.42 +expr_push_mul(expr_t expr, expr_t expr2); 38.43 + 38.44 +/* expr / expr2 */ 38.45 +void 38.46 +expr_push_div(expr_t expr, expr_t expr2); 38.47 + 38.48 +/* + expr */ 38.49 +void 38.50 +expr_push_plus(expr_t expr); 38.51 + 38.52 +/* - expr */ 38.53 +void 38.54 +expr_push_minus(expr_t expr); 38.55 + 38.56 +char 38.57 +expr_top_is_sign(expr_t expr); 38.58 + 38.59 +struct expr_signal_id * 38.60 +expr_bind_to_ports(expr_t expr, list_t ports); 38.61 + 38.62 +void 38.63 +expr_bind_consts(expr_t expr, list_t consts); 38.64 + 38.65 +char * 38.66 +expr_bind_ext_funcs(expr_t expr, list_t ext_funcs); 38.67 + 38.68 +struct expr_signal_id * 38.69 +expr_find_unbinded(expr_t expr); 38.70 + 38.71 +struct ext_func * 38.72 +expr_check_ext_func_args(expr_t expr); 38.73 + 38.74 +list_t 38.75 +expr_get_inputs(expr_t expr); 38.76 + 38.77 +list_t 38.78 +expr_get_refs(expr_t expr); 38.79 + 38.80 +list_t 38.81 +expr_get_df_refs(expr_t expr); 38.82 + 38.83 +list_t 38.84 +expr_get_delays(expr_t expr, struct scheduled_expr *ref); 38.85 + 38.86 +list_t 38.87 +expr_get_ext_funcs(expr_t); 38.88 + 38.89 +expr_t 38.90 +expr_copy(expr_t expr); 38.91 + 38.92 +void 38.93 +expr_port_to_value(expr_t expr, struct port *port, double value); 38.94 + 38.95 +void 38.96 +expr_port_to_ref(expr_t expr, struct port *port, struct scheduled_expr *ref); 38.97 + 38.98 +char 38.99 +expr_contains_ref(expr_t expr); 38.100 + 38.101 +char 38.102 +expr_contains_sample_rate(expr_t expr); 38.103 + 38.104 +char 38.105 +expr_is_const(expr_t expr); 38.106 + 38.107 +char 38.108 +expr_is_rt_const(expr_t expr); 38.109 + 38.110 +double 38.111 +expr_eval(expr_t expr); 38.112 + 38.113 +void 38.114 +expr_free(expr_t expr); 38.115 + 38.116 +void 38.117 +expr_dump(expr_t expr); 38.118 + 38.119 +void 38.120 +expr_c_compile(expr_t expr, FILE *fp, char inside_run); 38.121 + 38.122 +#endif /* !_EXPR_H_ */
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/permafrost/src/list.c Sun May 02 14:19:58 2010 +0300 39.3 @@ -0,0 +1,227 @@ 39.4 +/* 39.5 + * Permafrost - Physical modelling framework 39.6 + * 39.7 + * Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 39.8 + * 39.9 + * See the COPYING file for license conditions. 39.10 + */ 39.11 + 39.12 +#include <stdlib.h> 39.13 +#include <string.h> 39.14 + 39.15 +#include "src/list.h" 39.16 +#include "src/util.h" 39.17 + 39.18 +struct list_elem 39.19 + { 39.20 + struct list_elem *next; 39.21 + struct list_elem *prev; 39.22 + void *data; 39.23 + }; 39.24 + 39.25 +struct _list 39.26 + { 39.27 + struct list_elem *head; 39.28 + struct list_elem *tail; 39.29 + }; 39.30 + 39.31 +list_t 39.32 +list_new() 39.33 +{ 39.34 + list_t ret; 39.35 + 39.36 + ret = xmalloc(sizeof(struct _list)); 39.37 + ret->head = ret->tail = NULL; 39.38 + 39.39 + return ret; 39.40 +} 39.41 + 39.42 +void 39.43 +list_append(list_t list, void *data) 39.44 +{ 39.45 + struct list_elem *elem; 39.46 + 39.47 + elem = xmalloc(sizeof(struct list_elem)); 39.48 + elem->data = data; 39.49 + elem->next = NULL; 39.50 + if (list->head == NULL) 39.51 + { 39.52 + list->head = list->tail = elem; 39.53 + elem->prev = NULL; 39.54 + } 39.55 + else 39.56 + { 39.57 + elem->prev = list->tail; 39.58 + list->tail = elem; 39.59 + elem->prev->next = elem; 39.60 + } 39.61 +} 39.62 + 39.63 +void 39.64 +list_append_copy(list_t list, void *data, size_t size) 39.65 +{ 39.66 + void *p; 39.67 + 39.68 + p = xmalloc(size); 39.69 + memcpy(p, data, size); 39.70 + list_append(list, p); 39.71 +} 39.72 + 39.73 +void * 39.74 +list_pop(list_t list) 39.75 +{ 39.76 + void *p; 39.77 + 39.78 + if (list->tail == NULL) 39.79 + return NULL; 39.80 + 39.81 + p = list->tail->data; 39.82 + 39.83 + if (list->head == list->tail) 39.84 + { 39.85 + free(list->tail); 39.86 + list->head = list->tail = NULL; 39.87 + } 39.88 + else 39.89 + { 39.90 + list->tail = list->tail->prev; 39.91 + free(list->tail->next); 39.92 + list->tail->next = NULL; 39.93 + } 39.94 + 39.95 + return p; 39.96 +} 39.97 + 39.98 +void 39.99 +list_for_each(list_t list, void (*callback)(void *data, void *context), 39.100 + void *context) 39.101 +{ 39.102 + struct list_elem *elem; 39.103 + 39.104 + for (elem = list->head; elem != NULL; elem = elem->next) 39.105 + callback(elem->data, context); 39.106 +} 39.107 + 39.108 +void 39.109 +list_for_each_rev(list_t list, void (*callback)(void *data, void *context), 39.110 + void *context) 39.111 +{ 39.112 + struct list_elem *elem; 39.113 + 39.114 + for (elem = list->tail; elem != NULL; elem = elem->prev) 39.115 + callback(elem->data, context); 39.116 +} 39.117 + 39.118 +void * 39.119 +list_find(list_t list, int (*cmp)(void *d1, void *d2), void *data) 39.120 +{ 39.121 + struct list_elem *elem; 39.122 + 39.123 + for (elem = list->head; elem != NULL; elem = elem->next) 39.124 + if (cmp(elem->data, data) == 0) 39.125 + return elem->data; 39.126 + 39.127 + return NULL; 39.128 +} 39.129 + 39.130 +void 39.131 +list_merge(list_t list1, list_t list2) 39.132 +{ 39.133 + if (list2->head == NULL) 39.134 + /* do nothing */ ; 39.135 + else if (list1->head == NULL) 39.136 + { 39.137 + list1->head = list2->head; 39.138 + list1->tail = list2->tail; 39.139 + } 39.140 + else 39.141 + { 39.142 + list1->tail->next = list2->head; 39.143 + list2->head->prev = list1->tail; 39.144 + list1->tail = list2->tail; 39.145 + } 39.146 + 39.147 + free(list2); 39.148 +} 39.149 + 39.150 +void * 39.151 +list_get_last_data(list_t list) 39.152 +{ 39.153 + return (list->tail == NULL) ? NULL : list->tail->data; 39.154 +} 39.155 + 39.156 +char 39.157 +list_is_empty(list_t list) 39.158 +{ 39.159 + return list->head == NULL; 39.160 +} 39.161 + 39.162 +unsigned long 39.163 +list_get_n_elems(list_t list) 39.164 +{ 39.165 + struct list_elem *elem; 39.166 + unsigned long i; 39.167 + 39.168 + i = 0; 39.169 + for (elem = list->head; elem != NULL; elem = elem->next) 39.170 + i++; 39.171 + 39.172 + return i; 39.173 +} 39.174 + 39.175 +static void 39.176 +elem_copy(void *data, void *context) 39.177 +{ 39.178 + list_t list; 39.179 + 39.180 + list = (list_t)context; 39.181 + 39.182 + list_append(list, data); 39.183 +} 39.184 + 39.185 +list_t 39.186 +list_copy(list_t list) 39.187 +{ 39.188 + list_t ret; 39.189 + 39.190 + ret = list_new(); 39.191 + 39.192 + list_for_each(list, elem_copy, ret); 39.193 + 39.194 + return ret; 39.195 +} 39.196 + 39.197 +void 39.198 +list_free(list_t list) 39.199 +{ 39.200 + struct list_elem *p; 39.201 + 39.202 + if (list->head == NULL) 39.203 + /* do nothing */ ; 39.204 + else if (list->head == list->tail) 39.205 + free(list->head); 39.206 + else 39.207 + { 39.208 + for (p = list->head->next; p != NULL; p = p->next) 39.209 + free(p->prev); 39.210 + free(list->tail); 39.211 + } 39.212 + 39.213 + free(list); 39.214 +} 39.215 + 39.216 +#include <stdio.h> 39.217 + 39.218 +void 39.219 +list_dump(list_t list) 39.220 +{ 39.221 + struct list_elem *p; 39.222 + 39.223 + fprintf(stderr, "list: %p\nhead: %p, tail: %p\n", 39.224 + (void *)list, (void *)list->head, (void *)list->tail); 39.225 + 39.226 + for (p = list->head; p != NULL; p = p->next) 39.227 + fprintf(stderr, "elem: %p, next: %p, prev: %p, data: %p\n", 39.228 + (void *)p, (void *)p->next, (void *)p->prev, 39.229 + (void *)p->data); 39.230 +}
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/permafrost/src/list.h Sun May 02 14:19:58 2010 +0300 40.3 @@ -0,0 +1,62 @@ 40.4 +/* 40.5 + * Permafrost - Physical modelling framework 40.6 + * 40.7 + * Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 40.8 + * 40.9 + * See the COPYING file for license conditions. 40.10 + */ 40.11 + 40.12 +#ifndef _LIST_H_ 40.13 +#define _LIST_H_ 40.14 + 40.15 +#include <stddef.h> 40.16 + 40.17 +#include "src/types.h" 40.18 + 40.19 +list_t 40.20 +list_new(); 40.21 + 40.22 +void 40.23 +list_append(list_t list, void *data); 40.24 + 40.25 +void 40.26 +list_append_copy(list_t list, void *data, size_t size); 40.27 + 40.28 +#define list_push list_append 40.29 + 40.30 +void * 40.31 +list_pop(list_t list); 40.32 + 40.33 +void 40.34 +list_for_each(list_t list, void (*callback)(void *data, void *context), 40.35 + void *context); 40.36 + 40.37 +void 40.38 +list_for_each_rev(list_t list, void (*callback)(void *data, void *context), 40.39 + void *context); 40.40 + 40.41 +void * 40.42 +list_find(list_t list, int (*cmp)(void *d1, void *d2), void *data); 40.43 + 40.44 +void 40.45 +list_merge(list_t head, list_t tail); 40.46 + 40.47 +void * 40.48 +list_get_last_data(list_t list); 40.49 + 40.50 +char 40.51 +list_is_empty(list_t list); 40.52 + 40.53 +unsigned long 40.54 +list_get_n_elems(list_t list); 40.55 + 40.56 +list_t 40.57 +list_copy(list_t list); 40.58 + 40.59 +void 40.60 +list_free(list_t list); 40.61 + 40.62 +void 40.63 +list_dump(list_t list); 40.64 + 40.65 +#endif /* !_LIST_H_ */
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/permafrost/src/macro.c Sun May 02 14:19:58 2010 +0300 41.3 @@ -0,0 +1,454 @@ 41.4 +/* 41.5 + * Permafrost - Physical modelling framework 41.6 + * 41.7 + * Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 41.8 + * 41.9 + * See the COPYING file for license conditions. 41.10 + */ 41.11 + 41.12 +#include <stdlib.h> 41.13 +#include <stdio.h> 41.14 +#include <string.h> 41.15 + 41.16 +#include "src/types.h" 41.17 +#include "src/util.h" 41.18 +#include "src/list.h" 41.19 +#include "src/macro.h" 41.20 + 41.21 +void 41.22 +port_dump(void *data, void *context) 41.23 +{ 41.24 + struct port *p; 41.25 + 41.26 + p = (struct port *)data; 41.27 + 41.28 + printf(" %s %s `%s'\n", 41.29 + (p->sync == port_sync_sync) ? "sync" 41.30 + : ((p->sync == port_sync_async) ? "async" : "unknown"), 41.31 + (p->type == port_type_input) ? "input" 41.32 + : ((p->type == port_type_output) ? "output" 41.33 + : ((p->type == port_type_w) ? "w_port" : "k_port")), p->id); 41.34 +} 41.35 + 41.36 +void 41.37 +component_dump(void *data, void *context) 41.38 +{ 41.39 + struct component *c; 41.40 + 41.41 + c = (struct component *)data; 41.42 + 41.43 + printf(" %s `%s' `%s'\n", 41.44 + c->type.t.is_macro ? "macro" : "block", 41.45 + c->type.t.is_macro ? ((struct system *)c->type.t.p)->id 41.46 + : ((struct block *)c->type.t.p)->id, c->id); 41.47 +} 41.48 + 41.49 +void 41.50 +connection_dump(void *data, void *context) 41.51 +{ 41.52 + struct connection *c; 41.53 + 41.54 + c = (struct connection *)data; 41.55 + 41.56 + printf(" %s%s%s%s = ", 41.57 + (c->output.c.p.component != NULL) ? c->output.c.p.component->id 41.58 + : "", (c->output.c.p.component != NULL) ? "." : "", 41.59 + c->output.c.p.port->id, 41.60 + (c->output.type == conn_elem_type_port) ? "" 41.61 + : ((c->output.type == conn_elem_type_in) ? "in" : "out")); 41.62 + 41.63 + if (c->input.type == conn_elem_type_value) 41.64 + { 41.65 + printf("%f\n", c->input.c.value); 41.66 + return; 41.67 + } 41.68 + 41.69 + printf("%s%s%s%s\n", 41.70 + (c->input.c.p.component != NULL) 41.71 + ? c->input.c.p.component->id : "", 41.72 + (c->input.c.p.component != NULL) ? "." : "", 41.73 + c->input.c.p.port->id, 41.74 + (c->input.type == conn_elem_type_port) ? "" 41.75 + : ((c->input.type == conn_elem_type_in) ? "in" : "out")); 41.76 +} 41.77 + 41.78 +void 41.79 +system_dump(struct system *system) 41.80 +{ 41.81 + printf("system `%s':\n", system->id); 41.82 + 41.83 + printf(" ports:\n"); 41.84 + list_for_each(system->ports, port_dump, NULL); 41.85 + 41.86 + printf(" components:\n"); 41.87 + list_for_each(system->components, component_dump, NULL); 41.88 + 41.89 + printf(" connections:\n"); 41.90 + list_for_each(system->connections, connection_dump, NULL); 41.91 +} 41.92 + 41.93 +static int 41.94 +port_cmp_id(void *p, void *id) 41.95 +{ 41.96 + return strcmp(((struct port *)p)->id, (char *)id); 41.97 +} 41.98 + 41.99 +static int 41.100 +component_cmp_id(void *c, void *id) 41.101 +{ 41.102 + return strcmp(((struct component *)c)->id, (char *)id); 41.103 +} 41.104 + 41.105 +static void 41.106 +port_copy(void *data, void *context) 41.107 +{ 41.108 + struct port *port, *p; 41.109 + list_t list; 41.110 + 41.111 + port = (struct port *)data; 41.112 + list = (list_t)context; 41.113 + 41.114 + p = xmalloc(sizeof(struct port)); 41.115 + 41.116 + p->sync = port->sync; 41.117 + p->type = port->type; 41.118 + p->id = xmalloc(strlen(port->id) + 1); 41.119 + strcpy(p->id, port->id); 41.120 + 41.121 + list_append(list, p); 41.122 +} 41.123 + 41.124 +struct component_add_context 41.125 + { 41.126 + list_t list; 41.127 + char *prefix; 41.128 + }; 41.129 + 41.130 +static void 41.131 +component_add(void *data, void *context) 41.132 +{ 41.133 + struct component *comp, *c; 41.134 + struct component_add_context *ctx; 41.135 + struct component_add_context c_ctx; 41.136 + 41.137 + comp = (struct component *)data; 41.138 + ctx = (struct component_add_context *)context; 41.139 + 41.140 + if (!comp->type.t.is_macro) 41.141 + { 41.142 + c = xmalloc(sizeof(struct component)); 41.143 + 41.144 + c->id = xmalloc( 41.145 + ((ctx->prefix != NULL) ? strlen(ctx->prefix) : 0) 41.146 + + strlen(comp->id) + 1); 41.147 + if (ctx->prefix != NULL) 41.148 + strcpy(c->id, ctx->prefix); 41.149 + else 41.150 + *c->id = '\0'; 41.151 + strcat(c->id, comp->id); 41.152 + 41.153 + c->type.t.is_macro = 0; 41.154 + c->type.t.p = comp->type.t.p; 41.155 + 41.156 + list_append(ctx->list, c); 41.157 + 41.158 + return; 41.159 + } 41.160 + 41.161 + c_ctx.prefix = xmalloc(((ctx->prefix != NULL) ? strlen(ctx->prefix) : 0) 41.162 + + strlen(comp->id) + 2); 41.163 + if (ctx->prefix != NULL) 41.164 + strcpy(c_ctx.prefix, ctx->prefix); 41.165 + else 41.166 + *c_ctx.prefix = '\0'; 41.167 + strcat(c_ctx.prefix, comp->id); 41.168 + strcat(c_ctx.prefix, "."); 41.169 + c_ctx.list = ctx->list; 41.170 + 41.171 + list_for_each(((struct system *)comp->type.t.p)->components, 41.172 + component_add, &c_ctx); 41.173 + 41.174 + free(c_ctx.prefix); 41.175 +} 41.176 + 41.177 +struct conn_add_to_analogous_list_context 41.178 + { 41.179 + struct conn_elem *elem; 41.180 + list_t list; 41.181 + list_t ports; 41.182 + list_t components; 41.183 + struct component *base; 41.184 + char *prefix; 41.185 + }; 41.186 + 41.187 +static list_t 41.188 +conn_elem_analogous(struct conn_elem *elem, list_t ports, list_t components, 41.189 + struct component *base, char *prefix); 41.190 + 41.191 +static void 41.192 +conn_add_to_analogous_list(void *data, void *context) 41.193 +{ 41.194 + struct connection *conn; 41.195 + struct conn_add_to_analogous_list_context *ctx; 41.196 + list_t l; 41.197 + 41.198 + conn = (struct connection *)data; 41.199 + ctx = (struct conn_add_to_analogous_list_context *)context; 41.200 + 41.201 + if (conn->output.c.p.port == ctx->elem->c.p.port) 41.202 + { 41.203 + l = conn_elem_analogous(&conn->input, ctx->ports, 41.204 + ctx->components, ctx->base, 41.205 + ctx->prefix); 41.206 + list_merge(ctx->list, l); 41.207 + } 41.208 + 41.209 + if (conn->input.type == conn_elem_type_value) 41.210 + return; 41.211 + 41.212 + if (conn->input.c.p.port == ctx->elem->c.p.port) 41.213 + { 41.214 + l = conn_elem_analogous(&conn->output, ctx->ports, 41.215 + ctx->components, ctx->base, 41.216 + ctx->prefix); 41.217 + list_merge(ctx->list, l); 41.218 + } 41.219 +} 41.220 + 41.221 +static list_t 41.222 +conn_elem_analogous(struct conn_elem *elem, list_t ports, list_t components, 41.223 + struct component *base, char *prefix) 41.224 +{ 41.225 + list_t ret; 41.226 + struct conn_elem *e; 41.227 + struct conn_add_to_analogous_list_context ctx; 41.228 + char *id; 41.229 + 41.230 + ret = list_new(); 41.231 + if (elem->type == conn_elem_type_value) 41.232 + { 41.233 + e = xmalloc(sizeof(struct conn_elem)); 41.234 + 41.235 + e->type = conn_elem_type_value; 41.236 + e->c.value = elem->c.value; 41.237 + 41.238 + list_append(ret, e); 41.239 + } 41.240 + else if (elem->c.p.component == NULL) 41.241 + { 41.242 + if (base != NULL) 41.243 + return ret; 41.244 + 41.245 + e = xmalloc(sizeof(struct conn_elem)); 41.246 + 41.247 + e->type = elem->type; 41.248 + e->c.p.component = NULL; 41.249 + e->c.p.port = list_find(ports, port_cmp_id, elem->c.p.port->id); 41.250 + 41.251 + list_append(ret, e); 41.252 + } 41.253 + else if (!elem->c.p.component->type.t.is_macro) 41.254 + { 41.255 + e = xmalloc(sizeof(struct conn_elem)); 41.256 + 41.257 + e->type = elem->type; 41.258 + 41.259 + id = xmalloc(strlen(prefix) + strlen(elem->c.p.component->id) 41.260 + + 1); 41.261 + strcpy(id, prefix); 41.262 + strcat(id, elem->c.p.component->id); 41.263 + e->c.p.component = list_find(components, component_cmp_id, id); 41.264 + free(id); 41.265 + 41.266 + e->c.p.port = list_find( 41.267 + ((struct block *)elem->c.p.component->type.t.p)->ports, 41.268 + port_cmp_id, elem->c.p.port->id); 41.269 + 41.270 + list_append(ret, e); 41.271 + } 41.272 + else 41.273 + { 41.274 + ctx.elem = elem; 41.275 + ctx.list = ret; 41.276 + ctx.ports = ports; 41.277 + ctx.components = components; 41.278 + ctx.base = base; 41.279 + ctx.prefix = xmalloc(strlen(prefix) 41.280 + + strlen(elem->c.p.component->id) + 2); 41.281 + sprintf(ctx.prefix, "%s%s.", prefix, elem->c.p.component->id); 41.282 + list_for_each( 41.283 + ((struct system *)elem->c.p.component->type.t.p)->connections, 41.284 + conn_add_to_analogous_list, &ctx); 41.285 + free(ctx.prefix); 41.286 + } 41.287 + 41.288 + return ret; 41.289 +} 41.290 + 41.291 +struct conn_add_context 41.292 + { 41.293 + list_t list; 41.294 + struct conn_elem *output; 41.295 + }; 41.296 + 41.297 +static void 41.298 +conn_add(void *data, void *context) 41.299 +{ 41.300 + struct conn_elem *input; 41.301 + struct conn_add_context *ctx; 41.302 + struct connection *conn; 41.303 + 41.304 + input = (struct conn_elem *)data; 41.305 + ctx = (struct conn_add_context *)context; 41.306 + 41.307 + conn = xmalloc(sizeof(struct connection)); 41.308 + 41.309 + if (ctx->output->type == conn_elem_type_value) 41.310 + { 41.311 + conn->input = *ctx->output; 41.312 + conn->output = *input; 41.313 + } 41.314 + else if (input->type == conn_elem_type_value) 41.315 + { 41.316 + conn->input = *input; 41.317 + conn->output = *ctx->output; 41.318 + } 41.319 + else if (((ctx->output->c.p.component == NULL) 41.320 + && (ctx->output->c.p.port->type == port_type_input)) 41.321 + || ((ctx->output->c.p.component != NULL) 41.322 + && (ctx->output->c.p.port->type == port_type_output)) 41.323 + || ((input->c.p.component == NULL) 41.324 + && (input->c.p.port->type == port_type_output)) 41.325 + || ((input->c.p.component != NULL) 41.326 + && (input->c.p.port->type == port_type_input))) 41.327 + { 41.328 + conn->input = *ctx->output; 41.329 + conn->output = *input; 41.330 + } 41.331 + else 41.332 + { 41.333 + conn->input = *input; 41.334 + conn->output = *ctx->output; 41.335 + } 41.336 + free(ctx->output); 41.337 + 41.338 + list_append(ctx->list, conn); 41.339 +} 41.340 + 41.341 +struct conns_add_context 41.342 + { 41.343 + list_t list; 41.344 + list_t inputs; 41.345 + }; 41.346 + 41.347 +static void 41.348 +conns_add(void *data, void *context) 41.349 +{ 41.350 + struct conn_elem *output; 41.351 + struct conns_add_context *ctx; 41.352 + struct conn_add_context c_ctx; 41.353 + 41.354 + output = (struct conn_elem *)data; 41.355 + ctx = (struct conns_add_context *)context; 41.356 + 41.357 + c_ctx.list = ctx->list; 41.358 + c_ctx.output = output; 41.359 + list_for_each(ctx->inputs, conn_add, &c_ctx); 41.360 +} 41.361 + 41.362 +static void 41.363 +free_data(void *data, void *context) 41.364 +{ 41.365 + free(data); 41.366 +} 41.367 + 41.368 +struct 41.369 +connection_add_context 41.370 + { 41.371 + list_t list; 41.372 + list_t ports; 41.373 + list_t components; 41.374 + struct component *base; 41.375 + char *prefix; 41.376 + }; 41.377 + 41.378 +static void 41.379 +connection_add(void *data, void *context) 41.380 +{ 41.381 + struct connection *conn; 41.382 + struct connection_add_context *ctx; 41.383 + struct conns_add_context c_ctx; 41.384 + list_t outputs, inputs; 41.385 + 41.386 + conn = (struct connection *)data; 41.387 + ctx = (struct connection_add_context *)context; 41.388 + 41.389 + outputs = conn_elem_analogous(&conn->output, ctx->ports, 41.390 + ctx->components, ctx->base, ctx->prefix); 41.391 + inputs = conn_elem_analogous(&conn->input, ctx->ports, ctx->components, 41.392 + ctx->base, ctx->prefix); 41.393 + 41.394 + c_ctx.list = ctx->list; 41.395 + c_ctx.inputs = inputs; 41.396 + list_for_each(outputs, conns_add, &c_ctx); 41.397 + list_for_each(inputs, free_data, NULL); 41.398 +} 41.399 + 41.400 +static void 41.401 +connection_add_macro(void *data, void *context) 41.402 +{ 41.403 + struct component *comp; 41.404 + struct connection_add_context *ctx; 41.405 + struct connection_add_context m_ctx; 41.406 + 41.407 + comp = (struct component *)data; 41.408 + ctx = (struct connection_add_context *)context; 41.409 + 41.410 + if (!comp->type.t.is_macro) 41.411 + return; 41.412 + 41.413 + m_ctx.list = ctx->list; 41.414 + m_ctx.ports = ((struct system *)comp->type.t.p)->ports; 41.415 + m_ctx.components = ctx->components; 41.416 + m_ctx.base = comp; 41.417 + m_ctx.prefix = xmalloc(strlen(ctx->prefix) + strlen(comp->id) + 2); 41.418 + sprintf(m_ctx.prefix, "%s%s.", ctx->prefix, comp->id); 41.419 + list_for_each(((struct system *)comp->type.t.p)->connections, 41.420 + connection_add, &m_ctx); 41.421 + list_for_each(((struct system *)comp->type.t.p)->components, 41.422 + connection_add_macro, &m_ctx); 41.423 + free(m_ctx.prefix); 41.424 +} 41.425 + 41.426 +struct system * 41.427 +macro_to_blocks(struct system *system) 41.428 +{ 41.429 + struct system *s; 41.430 + struct component_add_context ctx; 41.431 + struct connection_add_context c_ctx; 41.432 + 41.433 + s = xmalloc(sizeof(struct system)); 41.434 + 41.435 + s->id = xmalloc(strlen(system->id) + 1); 41.436 + strcpy(s->id, system->id); 41.437 + 41.438 + s->ports = list_new(); 41.439 + list_for_each(system->ports, port_copy, s->ports); 41.440 + 41.441 + s->components = list_new(); 41.442 + ctx.prefix = NULL; 41.443 + ctx.list = s->components; 41.444 + list_for_each(system->components, component_add, &ctx); 41.445 + 41.446 + s->connections = list_new(); 41.447 + c_ctx.list = s->connections; 41.448 + c_ctx.ports = s->ports; 41.449 + c_ctx.components = s->components; 41.450 + c_ctx.base = NULL; 41.451 + c_ctx.prefix = ""; 41.452 + list_for_each(system->connections, connection_add, &c_ctx); 41.453 + 41.454 + list_for_each(system->components, connection_add_macro, &c_ctx); 41.455 + 41.456 + return s; 41.457 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/permafrost/src/macro.h Sun May 02 14:19:58 2010 +0300 42.3 @@ -0,0 +1,17 @@ 42.4 +/* 42.5 + * Permafrost - Physical modelling framework 42.6 + * 42.7 + * Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 42.8 + * 42.9 + * See the COPYING file for license conditions. 42.10 + */ 42.11 + 42.12 +#ifndef _MACRO_H_ 42.13 +#define _MACRO_H_ 42.14 + 42.15 +#include "src/types.h" 42.16 + 42.17 +struct system * 42.18 +macro_to_blocks(struct system *system); 42.19 + 42.20 +#endif /* !_MACRO_H_ */
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/permafrost/src/main.c Sun May 02 14:19:58 2010 +0300 43.3 @@ -0,0 +1,241 @@ 43.4 +/* 43.5 + * Permafrost - Physical modelling framework 43.6 + * 43.7 + * Copyright (C) 2009, 2010 Stefano D'Angelo <zanga.mail@gmail.com> 43.8 + * 43.9 + * See the COPYING file for license conditions. 43.10 + */ 43.11 + 43.12 +#include <stdlib.h> 43.13 +#include <stdio.h> 43.14 +#include <string.h> 43.15 + 43.16 +#include "src/util.h" 43.17 +#include "src/types.h" 43.18 +#include "src/list.h" 43.19 +#include "src/parser.h" 43.20 +#include "src/macro.h" 43.21 +#include "src/schedule.h" 43.22 +#include "src/compile.h" 43.23 + 43.24 +static const char **filenames = NULL; 43.25 +static size_t filenames_count = 0; 43.26 +static list_t block_systems; 43.27 +static list_t scheduled_systems; 43.28 +static char dry_run = 0; 43.29 + 43.30 +static void 43.31 +parse_cmd(int argc, char *argv[]) 43.32 +{ 43.33 + int i; 43.34 + 43.35 + for (i = 1; i < argc; i++) 43.36 + { 43.37 + if (!strcmp(argv[i], "--help")) 43.38 + { 43.39 + printf("Usage: %s [options] file...\n", argv[0]); 43.40 + printf("Options:\n"); 43.41 + printf(" --help Display this " 43.42 + "information\n"); 43.43 + printf(" --version Display the " 43.44 + "compiler version information\n"); 43.45 + printf(" --output-dir=<directory> Directory where to " 43.46 + "put generated files\n"); 43.47 + printf(" --dry-run Do not generate " 43.48 + "output files (implies all\n" 43.49 + " --no-<option> " 43.50 + "options)\n"); 43.51 + printf(" --no-code Do not generate " 43.52 + "source files (implies\n" 43.53 + " --no-descriptor " 43.54 + "and --no-makefile)\n"); 43.55 + printf(" --no-descriptor Do not generate " 43.56 + "lv2_descriptor.c (implies\n" 43.57 + " --no-makefile)" 43.58 + "\n"); 43.59 + printf(" --no-makefile Do not generate " 43.60 + "the Makefile\n"); 43.61 + printf(" --no-ttl Do not generate " 43.62 + ".ttl files (implies --no-manifest,\n" 43.63 + " --no-plugins-ttl " 43.64 + "and --no-extra-ttl)\n"); 43.65 + printf(" --no-manifest Do not generate " 43.66 + "manifest.ttl\n"); 43.67 + printf(" --no-plugin-ttl Do not generate " 43.68 + "plugin-specific .ttl files\n"); 43.69 + printf(" --no-extra-ttl Do not generate " 43.70 + "plugin-specific -extra.ttl files\n"); 43.71 + printf(" --uri-prefix=<prefix> Use <prefix> as " 43.72 + "the initial part of URIs\n"); 43.73 + printf(" --license-uri=<uri> Use <uri> as the " 43.74 + "DOAP license URI\n"); 43.75 + exit(EXIT_SUCCESS); 43.76 + } 43.77 + } 43.78 + 43.79 + for (i = 1; i < argc; i++) 43.80 + { 43.81 + if (!strcmp(argv[i], "--version")) 43.82 + { 43.83 + printf("permafrost (Permafrost) 0.2.0\n"); 43.84 + printf("Copyright (C) 2009, 2010 Stefano D'Angelo " 43.85 + "<zanga.mail@gmail.com>\n"); 43.86 + exit(EXIT_SUCCESS); 43.87 + } 43.88 + } 43.89 + 43.90 + for (i = 1; i < argc; i++) 43.91 + { 43.92 + if (argv[i][0] == '-') 43.93 + { 43.94 + if (!strncmp(argv[i], "--output-dir=", 43.95 + sizeof("--output-dir=") - 1)) 43.96 + { 43.97 + compile_output_dir = argv[i] - 1 43.98 + + sizeof("--output-dir="); 43.99 + continue; 43.100 + } 43.101 + if (!strcmp(argv[i], "--dry-run")) 43.102 + { 43.103 + dry_run = 1; 43.104 + continue; 43.105 + } 43.106 + if (!strcmp(argv[i], "--no-code")) 43.107 + { 43.108 + compile_gen_code = 0; 43.109 + compile_gen_descriptor = 0; 43.110 + compile_gen_makefile = 0; 43.111 + continue; 43.112 + } 43.113 + if (!strcmp(argv[i], "--no-descriptor")) 43.114 + { 43.115 + compile_gen_descriptor = 0; 43.116 + compile_gen_makefile = 0; 43.117 + continue; 43.118 + } 43.119 + if (!strcmp(argv[i], "--no-makefile")) 43.120 + { 43.121 + compile_gen_makefile = 0; 43.122 + continue; 43.123 + } 43.124 + if (!strcmp(argv[i], "--no-ttl")) 43.125 + { 43.126 + compile_gen_manifest = 0; 43.127 + compile_gen_plugin_ttl = 0; 43.128 + compile_gen_extra_ttl = 0; 43.129 + continue; 43.130 + } 43.131 + if (!strcmp(argv[i], "--no-manifest")) 43.132 + { 43.133 + compile_gen_manifest = 0; 43.134 + continue; 43.135 + } 43.136 + if (!strcmp(argv[i], "--no-plugin-ttl")) 43.137 + { 43.138 + compile_gen_plugin_ttl = 0; 43.139 + continue; 43.140 + } 43.141
