naspro

changeset 178:7169a8909d53 trunk naspro-0.2.0

Added Permafrost + small changes
author Stefano D'Angelo <zanga.mail@gmail.com>
date Sun May 02 14:19:58 2010 +0300 (21 months ago)
parents 1e775547efae
children 0a8479d7f88f
files naspro-bridges-bad/INSTALL naspro-core/CMakeLists.txt naspro-core/INSTALL permafrost/AUTHORS permafrost/CMakeLists.txt permafrost/COPYING permafrost/INSTALL permafrost/README permafrost/config.h.in permafrost/examples/Amp-extra.ttl permafrost/examples/Amp_dB-extra.ttl permafrost/examples/Arctan_waveshaper-extra.ttl permafrost/examples/Comb_filter_max_10_secs-extra.ttl permafrost/examples/Delay_10000_samples-extra.ttl permafrost/examples/Delay_10_samples-extra.ttl permafrost/examples/Delay_1_sample-extra.ttl permafrost/examples/Delay_1_sec-extra.ttl permafrost/examples/Delay_max_10_secs-extra.ttl permafrost/examples/First_order_FIR-extra.ttl permafrost/examples/Inverse_comb_filter_max_10_secs-extra.ttl permafrost/examples/One_pole_filter-extra.ttl permafrost/examples/Oscillator-extra.ttl permafrost/examples/RC_double_lowpass-extra.ttl permafrost/examples/RC_lowpass-extra.ttl permafrost/examples/Sawtooth-extra.ttl permafrost/examples/amp.pmf permafrost/examples/common.pmf permafrost/examples/delay.pmf permafrost/examples/filters.pmf permafrost/examples/funcgen.pmf permafrost/examples/rc_lowpass.pmf permafrost/examples/waveshaper.pmf permafrost/examples/wdf.pmf permafrost/lib/m.pmf permafrost/src/compile.c permafrost/src/compile.h permafrost/src/expr.c permafrost/src/expr.h permafrost/src/list.c permafrost/src/list.h permafrost/src/macro.c permafrost/src/macro.h permafrost/src/main.c permafrost/src/parser.c permafrost/src/parser.h permafrost/src/parser.tab.c permafrost/src/parser.tab.h permafrost/src/parser.y permafrost/src/scanner.c permafrost/src/scanner.h permafrost/src/scanner.l permafrost/src/schedule.c permafrost/src/schedule.h permafrost/src/types.h permafrost/src/util.c permafrost/src/util.h
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