Mike Gerwitz

Activist for User Freedom

aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am2
-rw-r--r--README.md33
-rw-r--r--bin/dslc.in28
-rwxr-xr-xbin/tame240
-rwxr-xr-xbin/tamed245
-rwxr-xr-xbootstrap36
-rw-r--r--build-aux/Makefile.2.in215
-rw-r--r--build-aux/Makefile.am230
-rwxr-xr-xbuild-aux/gen-c1make3
-rwxr-xr-xbuild-aux/gen-make14
-rw-r--r--build-aux/m4/calcdsl.m427
-rw-r--r--configure.ac10
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/about.texi193
-rw-r--r--doc/tame.texi6
-rw-r--r--rater/README.md6
l---------rater/c1map1
l---------rater/c1map.xsl1
l---------rater/calc.xsd1
l---------rater/compile.xsl1
l---------rater/compiler1
l---------rater/dot.xsl1
l---------rater/include1
l---------rater/link.xsl1
-rw-r--r--rater/rater.xsd1987
l---------rater/standalone.xsl1
l---------rater/summary.xsl1
l---------rater/tame1
-rw-r--r--src/current/include/preproc/template.xsl3
-rw-r--r--src/current/src/Makefile3
-rw-r--r--src/current/src/com/lovullo/dslc/DslCompiler.java19
32 files changed, 2956 insertions, 358 deletions
diff --git a/.gitignore b/.gitignore
index db0b056..d52e3f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
*.info
# autotools- and configure-generated
+/bin/dslc
/Makefile.in
/Makefile
/aclocal.m4
diff --git a/Makefile.am b/Makefile.am
index 01ac8a8..f543806 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
##
-SUBDIRS = doc progtest
+SUBDIRS = src/current/src doc progtest
path_src = src
path_test = test
diff --git a/README.md b/README.md
index fa67fe3..8222b25 100644
--- a/README.md
+++ b/README.md
@@ -14,12 +14,13 @@ designed to aid in the development, understanding, and maintenance of systems
performing numerous calculations on a complex graph of dependencies,
conditions, and a large number of inputs.
-This system was developed at LoVullo Associates to handle the complexity of
-comparative insurance rating systems. It is a domain-specific language (DSL)
-that itself encourages, through the use of templates, the creation of sub-DSLs.
-TAME itself is at heart a calculator—processing only numerical input and
-output—driven by quantifiers as predicates. Calculations and quantifiers are
-written declaratively without concern for order of execution.
+This system was developed at R-T Specialty (formerly LoVullo Associates) to
+handle the complexity of comparative insurance rating systems. It is a
+domain-specific language (DSL) that itself encourages, through the use of
+templates, the creation of sub-DSLs. TAME itself is at heart a
+calculator—processing only numerical input and output—driven by quantifiers
+as predicates. Calculations and quantifiers are written declaratively
+without concern for order of execution.
The system has powerful dependency resolution and data flow capabilities.
@@ -27,15 +28,10 @@ TAME consists of a macro processor (implementing a metalanguage), numerous
compilers for various targets (JavaScript, HTML documentation and debugging
environment, LaTeX, and others), linkers, and supporting tools. The input
grammar is XML, and the majority of the project (including the macro processor,
-compilers, and linkers) are written in XSLT. There is a reason for that odd
+compilers, and linkers) is written in XSLT. There is a reason for that odd
choice; until an explanation is provided, know that someone is perverted enough
to implement a full compiler in XSLT.
-More information will become available as various portions are liberated
-during refactoring. [tame-core](https://github.com/lovullo/tame-core) is
-TAME's core library, and [hoxsl](https://savannah.nongnu.org/projects/hoxsl)
-was developed as a supporting library.
-
## "Current"
The current state of the project as used in production is found in
@@ -54,6 +50,19 @@ instance. Available formats are:
- [Info][doc-info]
+## Getting Started
+To get started, make sure Saxon version 9 or later is available and its path
+set as `SAXON_CP`; that the path to hoxsl is set via `HOXSL`; and then run
+the `bootstrap` script:
+
+```bash
+$ export SAXON_CP=/path/to/saxon9he.jar
+$ export HOXSL=/path/to/hoxsl/root
+
+$ ./boostrap
+```
+
+
## Hacking
Information for TAME developers can be found in the file `HACKING`.
diff --git a/bin/dslc.in b/bin/dslc.in
new file mode 100644
index 0000000..e9dac7c
--- /dev/null
+++ b/bin/dslc.in
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Listen for TAME commands (compilers, linker, etc)
+#
+# Copyright (C) 2018 R-T Specialty, LLC.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# @AUTOGENERATED@
+##
+
+declare -r mypath=$( dirname "$( readlink -f "$0" )" )
+declare -r dslc_jar="$mypath/../src/current/src/dslc.jar"
+
+
+CLASSPATH="$CLASSPATH:@DSLC_CLASSPATH@:$dslc_jar" \
+ "@JAVA@" @JAVA_OPTS@ \
+ com.lovullo.dslc.DslCompiler
diff --git a/bin/tame b/bin/tame
new file mode 100755
index 0000000..ecb2bed
--- /dev/null
+++ b/bin/tame
@@ -0,0 +1,240 @@
+#!/bin/bash
+# Client for TAME daemon (tamed)
+#
+# Copyright (C) 2018 R-T Specialty, LLC.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+##
+
+set -euo pipefail
+
+declare -r mypath=$( dirname "$( readlink -f "$0" )" )
+
+declare -ri EX_NOTAMED=1 # tried to start tamed but failed
+declare -ri EX_USAGE=64 # incorrect usage; sysexits.h
+
+
+# Send a single command to a runner and observe the result
+#
+# stdin will be directed to the runner. stdout of the runner will be
+# echoed until a line beginning with "DONE" is found, after which this
+# procedure will return with the exit code indicated by the runner.
+command-runner()
+{
+ local -ri id="${1?Missing id}"
+ local -r root="${2?Missing root run path}"
+ shift 2
+
+ local -r base="$root/$id"
+ local -ri pid=$( cat "$base/pid" )
+
+ # TODO flock
+
+ verify-runner "$base" "$pid"
+
+ # forward signals to runner so that build is actually halted
+ # (rather than continuing in background after we die)
+ trap 'kill -TERM $pid &>/dev/null' INT TERM
+
+ # all remaining arguments are passed to the runner
+ echo "$@" > "$base/0"
+
+ # output lines from runner until we reach a line stating "DONE"
+ while read line; do
+ # don't parse words in the initial read because we may be
+ # dealing with a lot of lines
+ if [ "${line:0:5}" == "DONE " ]; then
+ read _ code _ <<< "$line"
+ return "$code"
+ fi
+
+ echo "$line"
+ done < "$base/1"
+}
+
+
+# Verify that a runner is available
+#
+# If the runner is offline or not owned by $UID, then exit with
+# a non-zero status.
+verify-runner()
+{
+ local -r base="${1?Missing base}"
+ local -ri pid="${2?Missing pid}"
+
+ ps "$pid" &>/dev/null || {
+ echo "error: runner $id ($pid) is offline!" >&2
+ exit "$EX_NOTAMED"
+ }
+
+ test -O "$base/0" || {
+ echo "error: runner $id ($pid) is not owned by $USER!" >&2
+ exit "$EX_NOTAMED"
+ }
+}
+
+
+# Wait somewhat impatiently for tamed
+#
+# Assumes that tamed's runner 0 is running once the pidfile becomes
+# available. Polls for a maximum of six seconds before giving up
+# and exiting with a non-zero status.
+wait-for-tamed()
+{
+ local -r base="${1?Missing base}"
+
+ # we could use inotify, but that is not installed by default
+ # on Debian systems, so let's just poll rather than introduce
+ # another dependency (give up after 6 seconds)
+ local -i i=12
+ while test $((i--)); do
+ test ! -f "$base/0/pid" || return 0
+ sleep 0.5
+ done
+
+ # still not available
+ echo 'error: tamed still unavailable; giving up' >&2
+ exit "$EX_NOTAMED"
+}
+
+
+# Start tamed if it is not already running
+#
+# If tamed is already running, nothing will happen; otherwise, start
+# tamed and wait impatiently for the runner to become available.
+#
+# Even if tamed is started, wait for runner 0 to become available;
+# this ensures that tamed is initialized even if this script is run
+# after tamed is started but before it has fully come online (e.g
+# parallel make).
+start-tamed()
+{
+ local -r root="${1?Missing root}"
+
+ local -ri pid=$( cat "$root/pid" 2>/dev/null )
+
+ ps "$pid" &>/dev/null || {
+ echo "starting tamed at $root..."
+
+ # tell tamed to clean up so that we eliminate race conditions
+ # with wait-for-tamed (this will also kill any stray processes
+ # that a previous tamed may have spawned but didn't get the
+ # chance to clean up)
+ kill-tamed "$root" || true
+
+ # start tamed and allow it to persist for future commands
+ "$mypath/tamed" "$root" & disown
+ }
+
+ # wait for tamed even if it was already started (just in
+ # case this script was executed right after tamed started
+ # but before it is done initializing)
+ wait-for-tamed "$root"
+}
+
+
+# Kill tamed
+#
+# Ask tamed to kill itself.
+kill-tamed()
+{
+ local -r root="${1?Missing root}"
+
+ "$mypath/tamed" --kill "$root"
+}
+
+
+# Filter dslc output to essential information
+#
+# The original output of dslc is quite noisy; this filters it down
+# to only errors and warnings.
+#
+# Eventually, dslc out to be modified to handle filtering its own
+# output rather than wasting cycles doing this filtering.
+saneout()
+{
+ awk ' \
+ /^~~~~\[begin /,/^~~~~\[end / { next } \
+ /^rm / { next } \
+ /^COMMAND / { next } \
+ /^Exception|^\t+at / { \
+ if ( /^E/ ) { \
+ print; \
+ print "Stack trace written to run-*.log"; \
+ } \
+ next; \
+ } \
+ /([Ww]arning|[Nn]otice)[: ]/ { printf "\033[0;33m"; w++; out=1; } \
+ /[Ff]atal:/ { printf "\033[0;31m"; out=1; } \
+ /!|[Ee]rror:/ { printf "\033[0;31m"; e++; out=1; } \
+ /internal:/ { printf "\033[0;35m"; out=1; } \
+ /internal error:/ { printf "\033[1m"; out=1; } \
+ /^[^[]/ || out { print; printf "\033[0;0m"; out=0; } \
+ '
+}
+
+
+# Output usage information and exit
+usage()
+{
+ cat <<EOF
+Usage: $0 [-v|--verbose] cmdline
+Or: $0 --kill
+Send command line CMDLINE to a tamed runner. Start tamed if
+not already running.
+
+Options:
+ --help show this message
+ --kill kill tamed
+ -v, --verbose show runner logs
+
+Environment Variables:
+ TAME_VERBOSE when greater than zero, show runner logs
+ (see also --verbose)
+EOF
+
+ exit $EX_USAGE
+}
+
+
+# Run tame
+main()
+{
+ local -r root=/run/user/$UID/tamed
+
+ local outcmd=saneout
+
+ test $# -gt 0 || usage
+
+ case "${1:-}" in
+ --kill) kill-tamed "$root"; exit;;
+ -v|--verbose) outcmd=cat;;
+ --help) usage;;
+ esac
+
+ # alternative to --verbose
+ if [ "${TAME_VERBOSE:-0}" -ge 1 ]; then
+ outcmd=cat
+ fi
+
+ start-tamed "$root"
+
+ # for now we only support a single runner
+ command-runner 0 "$root" "$@" \
+ | tee -a "run-0.log" \
+ | "$outcmd"
+}
+
+main "$@"
+
diff --git a/bin/tamed b/bin/tamed
new file mode 100755
index 0000000..25b2077
--- /dev/null
+++ b/bin/tamed
@@ -0,0 +1,245 @@
+#!/bin/bash
+# Daemon for accepting TAME commands (compilers, linker, etc)
+#
+# Copyright (C) 2018 R-T Specialty, LLC.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+##
+
+set -euo pipefail
+
+declare -r mypath=$( dirname "$( readlink -f "$0" )" )
+
+declare -ri EX_RUNNING=1
+declare -ri EX_USAGE=64 # incorrect usage; sysexits.h
+declare -ri EX_CANTCREAT=73 # cannot create file; sysexits.h
+
+# number of seconds before runners are considered unused and terminate
+declare -ri TAMED_STALL_SECONDS="${TAMED_STALL_SECONDS:-30}"
+
+# set by `main', global for `cleanup'
+declare root=
+
+
+# Create FIFOs for runner
+#
+# The FIFOs are intended to be attached to stderr and stdout
+# of the runner and will be created relative to the given
+# root path ROOT.
+#
+# If a FIFO cannot be created, exit with EX_CANTCREAT.
+mkfifos()
+{
+ local -r root="${1?Missing root path}"
+
+ mkdir -p "$root"
+
+ # note that there's no stderr; see `add-runner'
+ for n in 0 1; do
+ rm -f "$root-$n"
+
+ mkfifo -m 0600 "$root/$n" || {
+ echo "fatal: failed to create FIFO at $in"
+ exit $EX_CANTCREAT
+ }
+
+ # keep FIFOs open so we don't get EOF from writers
+ tail -f >"$root/$n" &
+ done
+}
+
+
+# Spawn a runner
+#
+# A new runner is created by spawning dslc and attaching
+# new FIFOs under the given id ID relative to the given
+# run path ROOT. The PID of the runner will be stored
+# alongside the FIFOs in a pidfile `pid'.
+spawn-runner()
+{
+ local -ri id="${1?Missing id}"
+ local -r root="${2?Missing root run path}"
+
+ local -r base="$root/$id"
+
+ mkfifos "$base"
+
+ # monitor runner usage and kill when inactive
+ stall-monitor "$base" &
+
+ # loop to restart runner in case of crash
+ while true; do
+ "$mypath/dslc" < "$base/0" &> "$base/1"
+ echo "warning: runner $id exited with code ${PIPESTATUS[0]}; restarting" >&2
+ done &
+
+ echo "$!" > "$base/pid"
+
+ echo "runner $id ($!): $base"
+}
+
+
+# Kill runner at BASE when it becomes inactive for TAMED_STALL_SECONDS
+# seconds
+#
+# This monitors the modification time on the stdout FIFO. stdin does not
+# need to be monitored since dslc immediately echoes back commands it
+# receives.
+#
+# dslc is pretty chatty at the time of writing this, so TAMED_STALL_SECONDS
+# can easily be <=30s even for large packages. This may need to change in
+# the future if it becomes too much less chatty. Increase that environment
+# variable if runners stall unexpectedly in the middle of builds.
+stall-monitor()
+{
+ local -r base="${1?Missing base}"
+
+ # monitor output FIFO modification time
+ while true; do
+ local -i since=$( date +%s )
+ sleep "$TAMED_STALL_SECONDS"
+ local -i last=$( stat -c%Y "$base/1" )
+
+ # keep waiting if there has been activity since $since
+ test "$last" -le "$since" || continue
+
+ # no activity; kill
+ local -r pid=$( cat "$base/pid" )
+ kill "$pid"
+ wait "$pid" 2>/dev/null
+
+ # this stall subprocess is no longer needed
+ break
+ done
+}
+
+
+# Exit if tamed is already running at path ROOT
+#
+# If tamed is already running at ROOT, exit with status
+# EX_RUNNING; otherwise, do nothing except output a warning
+# if a stale pid file exists.
+abort-if-running()
+{
+ local -r root="${1?Missing root rundir}"
+
+ local -ri pid=$( cat "$root/pid" 2>/dev/null )
+
+ test "$pid" -gt 0 || return 0
+
+ ! ps "$pid" &>/dev/null || {
+ echo "fatal: tamed is already running at $root (pid $pid)!"
+ exit $EX_RUNNING
+ }
+
+ test -z "$pid" || {
+ echo "warning: clearing stale tamed (pid $pid)"
+ }
+}
+
+
+# Kill running tamed at path ROOT
+#
+# If no pidfile is found at ROOT, do nothing. This sends a
+# signal only to the parent tamed process, _not_ individual
+# runners; the target tamed is expected to clean up itself.
+# Consequently, if a tamed terminated abnormally without
+# cleaning up, this will not solve that problem.
+kill-running()
+{
+ local -r root="${1?Missing root}"
+
+ local -r pid=$( cat "$root"/pid 2>/dev/null )
+
+ test -n "$pid" || return 0
+
+ echo "killing tamed at $root ($pid)..."
+ kill "$pid"
+}
+
+
+# Clean up child processes before exit
+#
+# This should be called before exit (perhaps by a trap). Kills
+# the entire process group.
+#
+# Do not attach this to a SIGTERM trap or it will infinitely
+# recurse.
+cleanup()
+{
+ rm -rf "$root"
+ kill 0
+}
+
+
+# Output usage information and exit
+usage()
+{
+ cat <<EOF
+Usage: $0 [--kill] [runpath]
+Start tamed and runners. Do not fork into background process.
+
+The default value of RUNPATH is \`/run/user/$UID/tamed'.
+
+Only one runner is currently supported. tamed exits once all
+runners have terminated. Runners will be killed once they are
+inactive for at least TAMED_STALL_SECONDS (default 30).
+
+Options:
+ --help show this message
+ --kill kill a runing tamed at path RUNPATH
+
+Environment Variables:
+ TAMED_STALL_SECONDS number of seconds of runner inactivity before
+ runner is automatically killed (default 30)
+EOF
+
+ exit $EX_USAGE
+}
+
+
+# Run tamed
+main()
+{
+ local kill=
+ case "${1:-}" in
+ --kill) kill=1; shift;;
+ --help) usage;;
+ esac
+
+ root="${1:-/run/user/$UID/tamed}"
+
+ # kill if requested
+ test -z "$kill" || {
+ kill-running "$root"
+ exit
+ }
+
+ abort-if-running "$root"
+
+ # clean up background processes before we exit
+ trap exit TERM
+ trap cleanup EXIT
+
+ # start fresh
+ rm -rf "$root"; mkdir -p "$root"
+ echo $$ > "$root/pid"
+
+ # only a single runner for now
+ spawn-runner 0 "$root"
+
+ wait -n
+}
+
+main "$@"
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..6b6fcda
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,36 @@
+#!/bin/bash
+# Bootstrap from source repository
+#
+# Copyright (C) 2018 R-T Specialty, LLC.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+##
+
+set -euo pipefail
+
+export SAXON_CP="${SAXON_CP?Missing path to saxon9he.jar}"
+export RATER_CLASSPATH="${RATER_CLASSPATH:-$SAXON_CP}"
+export HOXSL="${HOXSL?Missing path to hoxsl}"
+
+test "${1:-}" = -n || git submodule update --init --recursive
+
+cd progtest \
+ && { which npm && npm install || true; } \
+ && ./autogen.sh && ./configure \
+ && cd - \
+ && { test -e hoxsl || ln -s ../hoxsl; } \
+ && autoreconf -fvi \
+ && ./configure \
+ && make all
+
diff --git a/build-aux/Makefile.2.in b/build-aux/Makefile.2.in
deleted file mode 100644
index 5618833..0000000
--- a/build-aux/Makefile.2.in
+++ /dev/null
@@ -1,215 +0,0 @@
-# @configure_input@
-#
-# Compiles packages written in the Calc DSL.
-#
-# Copyright (C) 2018 R-T Specialty, LLC.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# Note that this build process is unconventional in order to avoid the startup
-# costs that would be associated with executing dslc with each and every package
-# (see the other Makefile for more information). Therefore, everything is
-# written to .cqueue for later processing by dslc.
-#
-# The issue of re-building based on timestamps---which Make would normally take
-# care of exclusively---must also be given special care now that we are handling
-# the building separately from Make. Each enqueued request also touches the
-# destination file to update its timestamp, ensuring that it is seen by Make as
-# modified (as if it were compiled) and therefore will trigger the building of
-# the targets that depend upon it. In the case of the object files (xmlo), a
-# temporary file is created when it is enqueued. As part of the queued request
-# for compilation is a request to delete this temporary file. In the event that
-# the build fails, this temporary file will be seen and will force a rebuild of
-# the file, despite its timestamp.
-#
-# The same issue does not exist for xmle, js, and html files, since they have
-# linear dependency trees and dslc will rm the file on failure, which
-# obliterates the timestamp.
-# #
-
-path_rates := $(path_suppliers)/rates
-path_map := map
-path_c1map := $(path_map)/c1
-path_dsl := rater
-path_ui := ui
-path_suppliers := suppliers
-path_lv := lovullo
-path_srv := srv
-
-src_suppliers := $(wildcard $(path_suppliers)/*.xml)
-src_map := $(wildcard $(path_map)/*.xml)
-src_c1map := $(wildcard $(path_c1map)/*.xml)
-
-dest_summary_html := $(patsubst \
- $(path_suppliers)/%.xml, \
- $(path_suppliers)/%.html, \
- $(src_suppliers))
-dest_standalone := $(patsubst \
- $(path_suppliers)/%.xml, \
- $(path_suppliers)/%.js, \
- $(src_suppliers))
-dest_map := $(patsubst \
- $(path_map)/%.xml, \
- $(path_map)/%.xmle, \
- $(src_map))
-dest_c1map := $(patsubst \
- $(path_c1map)/%.xml, \
- $(path_c1map)/%.php, \
- $(src_c1map))
-
-compiled_suppliers := $(src_suppliers:.xml=.xmlo)
-linked_suppliers := $(src_suppliers:.xml=.xmle)
-
-comma := ,
-extless_supp_delim := $(subst .xml,,$(subst .xml ,$(comma),$(src_suppliers)))
-
-cqueue=.cqueue
-
-ant = @ANT@ -e
-
-.DELETE_ON_ERROR:
-
-.PHONY: default clean \
- interp-rate-tables summary-html c1map \
- standalones program-ui program-ui-immediate program-data-copy \
- do-build version FORCE
-
-# these files will never be deleted when Make considers them to be intermediate
-# (e.g. when building summary pages), since they are still needed or take a
-# while to build
-.PRECIOUS: %.js %.xml %.xmle %.xmlo
-
-SHELL = /bin/bash -O extglob
-
-default: program-ui c1map FORCE
-
-program-ui: standalones ui/package.js ui/Program.js program-ui-immediate
-program-ui-immediate: ui/html/index.phtml
-
-include suppliers.mk
-
-# starts with a fresh cqueue
-prexmlo:
- @>$(cqueue)
-
-summary-html: $(dest_summary_html) ;
-
-%.html: %.js
- @echo "summary $*.xmle $@" >>.cqueue
- @touch $@
-
-standalones: $(dest_standalone)
-%.xmle: %.xmlo
- @echo "link $< $@" >>.cqueue
- @touch $@
-%.js: %.xmle
- @echo "standalone $< $@" >>.cqueue
- @touch $@
-
-# C1 XML (specific recipes are in suppliers.mk)
-c1map: $(dest_c1map)
-
-%.dot: %.xmlo
- @echo "dot $< $@" >> .cqueue
-%.dote: %.xmle
- @echo "dot $< $@" >> .cqueue
-
-%.svg: %.dote
- dot -Tsvg "$<" > "$@"
-%.svg: %.dot
- dot -Tsvg "$<" > "$@"
-
-%.xml: %.dat
- rater/tools/tdat2xml $< > $@
-
-%.xml: %.typelist
- rater/tame/build-aux/list2typedef $(*F) < $< > $@
-
-%.csvo: %.csvm
- rater/tools/csvm2csv $< > $@
-%.csvo: %.csvi
- rater/tools/csvi $< > $@
-%.csvo: %.csv
- cp $< $@
-
-%.xml: %.csvo
- rater/tools/csv2xml $< > $@
-
-version: .version.xml
-.version.xml: FORCE
- git log HEAD^.. -1 --pretty=format:'<version>%h</version>' > .version.xml
-
-ui/program.expanded.xml: ui/program.xml | .version.xml
- @echo "progui-expand $< $@" >> .cqueue
-ui/Program.js: ui/program.expanded.xml ui/package.js
- @echo "progui-class $< $@ include-path=../../../ui/" >> .cqueue
-ui/html/index.phtml: ui/program.expanded.xml
- @echo "progui-html $< $@ out-path=./" >> .cqueue
-ui/package-dfns.xmlo: ui/package-dfns.xml
-ui/package-dfns.xml: ui/program.expanded.xml
- @echo "progui-pkg $< $@" >> .cqueue
-ui/package-map.xmlo: ui/package-map.xml
-ui/package-map.xml: ui/program.expanded.xml ui/package-dfns.xml
- @echo "progui-pkg-map $< $@" >> .cqueue
-
-# for the time being, this does not depend on clean-rate-tables because $(ant) will
-specs:
- $(MAKE) -C doc/specs
- #
-# this will eventually go away once we don't have X-repo klugery
-
-# for the time being, this does not depend on clean-rate-tables because ant will
-# run it
-clean:
- find $(path_suppliers) $(path_map) $(path_c1map) common/ rater/core rater/lv \( \
- -name '*.xmlo' \
- -o -name '*.xmle' \
- -o -name '*.js' \
- -o -name '*.html' \
- -o -name '*.dep' \
- -o -name '*.tmp' \
- \) -exec rm -v {} \;
- rm -rf $(path_ui)/package-dfns.* \
- $(path_ui)/package-map.* \
- $(path_ui)/program.expanded.xml \
- $(path_ui)/include.js \
- $(path_ui)/Program.js \
- $(path_ui)/html
- find . -path '*/tables/*.csvm' -o -path '*/territories/*.dat' \
- | sed 's/\.csvm$$/\.xml/; s/\.dat$$/\.xml/' \
- | xargs rm -fv
-
-# generates a Makefile that will properly build all package dependencies; note
-# that territory and rate packages also have includes; see top of this file for
-# an explanation
-suppliers.mk:
- $(ant) pkg-dep \
- && mv $(path_ui)/program.dep $(path_ui)/package-dfns.dep
- xmlo_cmd='@echo "validate $$(patsubst %.tmp,%.xml,$$<) $$@" >> .cqueue \
- && echo "compile $$(patsubst %.tmp,%.xml,$$<) $$@" >> .cqueue \
- && echo "rm $$(patsubst %.xmlo,%.tmp,$$@)" >> .cqueue \
- && touch $$@ \
- && touch -d +1sec $$(patsubst %.xmlo,%.tmp,$$@) >> .cqueue' \
- ./rater/tame/build-aux/gen-make common/ $(path_suppliers)/ $(path_dsl)/ $(path_map)/ $(path_ui)/ >$@ \
- && ./rater/tame/build-aux/gen-c1make $(path_c1map)/*.xml >>$@
-
-me-a-sandwich:
- @test $$EUID -eq 0 \
- && echo 'You actually ran me as root? Are you insane!?' \
- || echo 'Make it yourself.'
-
-# simply forces a job to run, thereby forcing the invocation of the secondary
-# Makefile (this is not explicitly required, because of prepare, but signifies
-# intent and is self-documenting)
-FORCE: ;
diff --git a/build-aux/Makefile.am b/build-aux/Makefile.am
index 4ddec3b..73555ba 100644
--- a/build-aux/Makefile.am
+++ b/build-aux/Makefile.am
@@ -16,15 +16,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# This fragment exists as a kluge to provide support for running a command
-# after all targets have been run (in this case, dslc).
-#
-# A list of everything to be compiled is output into .cqueue, which is then
-# picked up by dslc; this avoids the overhead of starting the JVM,
-# recompiling XSL stylesheets, etc, which is quite substantial.
-#
-# !!! Unfortunately, this does not yet support parallel job execution.
+##
path_rates := $(path_suppliers)/rates
path_map := map
@@ -38,63 +30,153 @@ path_srv := srv
path_lvroot := lvroot
path_intralov_root := "intralov-root/@program@"
-.PHONY: FORCE prepare program-data-copy lvroot program-ui-immediate test
-
-JAVA_HEAP_SIZE ?= 5120M
-JAVA_STACK_SIZE ?= 5M
+src_suppliers := $(wildcard $(path_suppliers)/*.xml)
+src_map := $(wildcard $(path_map)/*.xml)
+src_c1map := $(wildcard $(path_c1map)/*.xml)
+
+dest_summary_html := $(patsubst \
+ $(path_suppliers)/%.xml, \
+ $(path_suppliers)/%.html, \
+ $(src_suppliers))
+dest_standalone := $(patsubst \
+ $(path_suppliers)/%.xml, \
+ $(path_suppliers)/%.js, \
+ $(src_suppliers))
+dest_map := $(patsubst \
+ $(path_map)/%.xml, \
+ $(path_map)/%.xmle, \
+ $(src_map))
+dest_c1map := $(patsubst \
+ $(path_c1map)/%.xml, \
+ $(path_c1map)/%.php, \
+ $(src_c1map))
+
+compiled_suppliers := $(src_suppliers:.xml=.xmlo)
+linked_suppliers := $(src_suppliers:.xml=.xmle)
+
+comma := ,
+extless_supp_delim := $(subst .xml,,$(subst .xml ,$(comma),$(src_suppliers)))
+
+ant = @ANT@ -e
+
+.PHONY: FORCE default program-data-copy lvroot program-ui-immediate test \
+ default clean interp-rate-tables summary-html c1map standalones \
+ program-ui version FORCE
+
+default: program-ui c1map FORCE
.DELETE_ON_ERROR:
-
-# less verbose output; all to runlog
-define saneout
- time -f 'total time: %E' awk ' \
- BEGIN { e=0; w=0; } \
- { printf "[%d] ", systime() >> ".runlog"; print >> ".runlog"; } \
- /^~~~~\[begin /,/^~~~~\[end / { next } \
- /^rm / { next } \
- /^Exception|^\t+at / { \
- if ( /^E/ ) { \
- print; \
- print "Stack trace written to .runlog"; \
- } \
- next; \
- } \
- /[Ww]arning:|[Nn]otice:/ { printf "\033[0;33m"; w++; out=1; } \
- /[Ff]atal:/ { printf "\033[0;31m"; out=1; } \
- /!|[Ee]rror:/ { printf "\033[0;31m"; e++; out=1; } \
- /internal:/ { printf "\033[0;35m"; out=1; } \
- /internal error:/ { printf "\033[1m"; out=1; } \
- /^[^[]/ || out { print; printf "\033[0;0m"; out=0; } \
- END { printf "%d error(s); %d warning(s).\n", e, w; } \
- '
-endef
-
-define _go
- touch .cqueue \
- && ( test -s .cqueue || echo "Nothing to be done for \`$@'." ) \
- && echo "$(JAVA_HEAP_SIZE) $(JAVA_STACK_SIZE)" \ \
- && CLASSPATH="$(RATER_CLASSPATH):rater/src/dslc.jar" \
- $(JAVA) -Xmx$(JAVA_HEAP_SIZE) -Xss$(JAVA_STACK_SIZE) \
- com.lovullo.dslc.DslCompiler < .cqueue 2>&1 \
- | $(saneout); \
- exit $${PIPESTATUS[0]}; \
- @>.cqueue
-endef
+.NOTPARALLEL:
SHELL = /bin/bash -O extglob
-all: program-data-copy
+# these files will never be deleted when Make considers them to be intermediate
+# (e.g. when building summary pages), since they are still needed or take a
+# while to build
+.SECONDARY: %.js %.xml %.xmle %.xmlo
-program-ui-immediate:
- @>.cqueue
- @$(MAKE) --no-print-directory -f Makefile.2 program-ui-immediate
- @$(MAKE) program-data-copy
- @$(_go)
+all: program-data-copy
-program-data-copy:
- @>.cqueue
- @$(MAKE) --no-print-directory -f Makefile.2 standalones program-ui c1map
- @$(_go)
+program-ui: standalones ui/package.js ui/Program.js program-ui-immediate
+program-ui-immediate: ui/html/index.phtml
+
+# Note the `$()' here to prevent Automake from inlining this file---it is
+# to be generated when imports change, which can be at any time.
+include $()suppliers.mk
+
+summary-html: $(dest_summary_html) ;
+
+%.html: %.js
+ $(TAME) summary $*.xmle $@
+
+standalones: $(dest_standalone)
+%.xmle: %.xmlo
+ $(TAME) link $< $@
+%.js: %.xmle
+ $(TAME) standalone $< $@
+
+# C1 XML (specific recipes are in suppliers.mk)
+c1map: $(dest_c1map)
+
+%.dot: %.xmlo
+ $(TAME) dot $< $@
+%.dote: %.xmle
+ $(TAME) dot $< $@
+
+%.svg: %.dote
+ dot -Tsvg "$<" > "$@"
+%.svg: %.dot
+ dot -Tsvg "$<" > "$@"
+
+%.xml: %.dat
+ rater/tools/tdat2xml $< > $@
+
+%.xml: %.typelist
+ rater/tame/build-aux/list2typedef $(*F) < $< > $@
+
+%.csvo: %.csvm
+ rater/tools/csvm2csv $< > $@
+%.csvo: %.csvi
+ rater/tools/csvi $< > $@
+%.csvo: %.csv
+ cp $< $@
+
+%.xml: %.csvo
+ rater/tools/csv2xml $< > $@
+
+version: .version.xml
+.version.xml: FORCE
+ git log HEAD^.. -1 --pretty=format:'<version>%h</version>' > .version.xml
+
+ui/program.expanded.xml: ui/program.xml
+ $(TAME) progui-expand $< $@
+ui/Program.js: ui/program.expanded.xml ui/package.js
+ $(TAME) progui-class $< $@ include-path=../../../ui/
+ui/html/index.phtml: ui/program.expanded.xml
+ $(TAME) progui-html $< $@ out-path=./
+ui/package-dfns.xmlo: ui/package-dfns.xml
+ui/package-dfns.xml: ui/program.expanded.xml
+ $(TAME) progui-pkg $< $@
+ui/package-map.xmlo: ui/package-map.xml
+ui/package-map.xml: ui/program.expanded.xml ui/package-dfns.xml
+ $(TAME) progui-pkg-map $< $@
+
+# for the time being, this does not depend on clean-rate-tables because $(ant) will
+specs:
+ $(MAKE) -C doc/specs
+
+# for the time being, this does not depend on clean-rate-tables because ant will
+# run it
+clean:
+ find -L $(path_suppliers) $(path_map) $(path_c1map) common/ rater/core rater/lv \( \
+ -name '*.xmlo' \
+ -o -name '*.xmle' \
+ -o -name '*.js' \
+ -o -name '*.html' \
+ -o -name '*.dep' \
+ -o -name '*.tmp' \
+ -o -name '*.php' \
+ \) -exec rm -v {} \;
+ rm -rf $(path_ui)/package-dfns.* \
+ $(path_ui)/package-map.* \
+ $(path_ui)/program.expanded.xml \
+ $(path_ui)/include.js \
+ $(path_ui)/Program.js \
+ $(path_ui)/html
+ find . -path '*/tables/*.csvm' -o -path '*/territories/*.dat' \
+ | sed 's/\.csvm$$/\.xml/; s/\.dat$$/\.xml/' \
+ | xargs rm -fv
+
+# generates a Makefile that will properly build all package dependencies; note
+# that territory and rate packages also have includes; see top of this file for
+# an explanation
+suppliers.mk:
+ $(ant) pkg-dep
+ mv $(path_ui)/program.dep $(path_ui)/package-dfns.dep
+ ./rater/tame/build-aux/gen-make common/ $(path_suppliers)/ $(path_dsl)/ $(path_map)/ $(path_ui)/ >$@
+ ./rater/tame/build-aux/gen-c1make $(path_c1map)/*.xml >>$@
+
+program-data-copy: standalones program-ui c1map .version.xml
mkdir -p "$(path_lv)/src/node/program/rater/programs/@program@"
mkdir -p "$(path_lv)/src/node/program/classify"
mkdir -p "$(path_lv)/src/node/program/ui/custom"
@@ -124,7 +206,7 @@ program-data-copy:
ant -f "$(path_lv)/build.xml" js-mod-order
# TODO: merge this and the above
-lvroot: prepare
+lvroot: summary-html
mkdir -p "$(path_lvroot)/src/node/program/rater/programs/@program@"
mkdir -p "$(path_lvroot)/src/node/program/classify"
mkdir -p "$(path_lvroot)/src/node/program/ui/custom"
@@ -155,28 +237,18 @@ intralov-root: summary-html
ln -fL $(path_dsl)/scripts/*.js "$(path_intralov_root)/rater/scripts/"
ln -fL $(path_suppliers)/*.{html,js} "$(path_intralov_root)/suppliers"
-
-# because of the crazy wildcard target below, we want to ignore
-# some Automake-generated stuff
-%.am:
-%.m4:
-%.ac:
-
-%: prepare
- @if [[ "$@" != [Mm]akefile ]]; then \
- $(MAKE) --no-print-directory -f Makefile.2 $@; \
- $(_go); \
- fi
-
-clean:
- $(MAKE) --no-print-directory -f Makefile.2 clean
-
-prepare: FORCE
- @>.cqueue
-
test: check
check-am: standalones ui/package.js
@$(path_dsl)/build-aux/progtest-runner $(path_suppliers) $(path_tests)
@$(path_dsl)/build-aux/progtest-runner ui/package.xml $(path_tests)/ui
+kill-tamed: tamed-die
+tamed-die:
+ $(TAME) --kill
+
+me-a-sandwich:
+ @test $$EUID -eq 0 \
+ && echo 'You actually ran me as root? Are you insane!?' \
+ || echo 'Make it yourself.'
+
FORCE: ;
diff --git a/build-aux/gen-c1make b/build-aux/gen-c1make
index 3de7a2b..ed7ffdb 100755
--- a/build-aux/gen-c1make
+++ b/build-aux/gen-c1make
@@ -75,8 +75,7 @@ c1recipe()
)
echo "$dir/$base.php: $file $includes"
- echo -e '\t@echo "c1map $< $@" >> .cqueue'
- echo -e '\t@touch $@'
+ echo -e '\t$(TAME) c1map $< $@'
}
diff --git a/build-aux/gen-make b/build-aux/gen-make
index fbed524..63aa436 100755
--- a/build-aux/gen-make
+++ b/build-aux/gen-make
@@ -54,16 +54,8 @@ resolv-path()
# rule for building
[ -z "$GEN_MAKE" ] && {
- echo "%.xmlo:: %.tmp"
- echo -e "\t@rm -f \$@ \$<"
- [ -n "$xmlo_cmd" ] \
- && echo -e "\t$xmlo_cmd" \
- || echo -e "\ttouch \$@"
-
- echo "%.xmlo:: %.xml | prexmlo"
- [ -n "$xmlo_cmd" ] \
- && echo -e "\t$xmlo_cmd" \
- || echo -e "\ttouch \$@"
+ echo "%.xmlo: %.xml"
+ echo -e '\t$(TAME) compile $< $@'
export GEN_MAKE="$( pwd )/$0"
exec "$GEN_MAKE" "$@"
@@ -119,6 +111,8 @@ until [ $# -eq 0 ]; do (
# recurse on every subdirectory
for p in */; do
[ "$p" == ./ -o "$p" == ../ ] && continue
+ [ "$p" == node_modules/ -o "$p" == tame/ ] && continue
+
[ ! -d "$p" ] || ( cd "$OLDPWD" && "$GEN_MAKE" "$path/$p" ) || {
echo "fatal: failed to recurse on $( pwd )/$path/$p" >&2
exit 1
diff --git a/build-aux/m4/calcdsl.m4 b/build-aux/m4/calcdsl.m4
index 18f8ab5..d846fa0 100644
--- a/build-aux/m4/calcdsl.m4
+++ b/build-aux/m4/calcdsl.m4
@@ -33,13 +33,10 @@ AM_INIT_AUTOMAKE([foreign])
AC_ARG_VAR([JAVA], [The Java executable])
AC_ARG_VAR([ANT], [Apache Ant])
AC_ARG_VAR([DSLC_JAR], [Path to DSL Compiler JAR])
-AC_ARG_VAR([TAME], [Path to TAME])
+AC_ARG_VAR([TAME], [The TAME compiler])
AC_ARG_VAR([RATER_CLASSPATH], [DSL Compiler Saxon class path])
AC_ARG_VAR([PROGUI_TEST_PATH], [Path to JavaScript tests for Program UI])
-# Required version of TAME
-AC_SUBST([tame_needed_ver], [1.0.0])
-
# Auto-discover Java and Ant paths
AC_CHECK_PROGS(JAVA, [java])
AC_CHECK_PROGS(ANT, [ant])
@@ -64,34 +61,18 @@ AS_IF([test ! "$DSLC_JAR"],
# TAME is the compiler (whereas dslc invokes it, keeps things in memory, etc)
AS_IF([test ! "$TAME"],
- [AC_CHECK_FILE([$CALCROOT/tame],
- [AC_SUBST([TAME], [$CALCROOT/tame])],
+ [AC_CHECK_FILE([$CALCROOT/tame/bin/tame],
+ [AC_SUBST([TAME], [$CALCROOT/tame/bin/tame])],
[AC_MSG_ERROR(
[TAME not found])])],
[])
-AC_MSG_CHECKING([TAME version])
-
-AC_SUBST_FILE([tame_version])
-tame_version=$( cat "$TAME/VERSION" )
-
-# We get subtle errors or potential compiler bugs if the TAME version is
-# incorrect; check for >= the required version
-AS_VERSION_COMPARE([$tame_version], [$tame_needed_ver],
- [
- AC_MSG_RESULT([$tame_version])
- AC_MSG_ERROR([TAME version $tame_needed_ver or greater required])
- ],
- [AC_MSG_RESULT([$tame_version])],
- [AC_MSG_RESULT([$tame_version (>$tame_needed_ver)])])
-
# @program@ in *.in files will be replaced with the program name provided by AC_INIT
AC_SUBST([program], AC_PACKAGE_NAME)
# Final files to be output by `configure'. The path before the colon is the
# destination name; after the colon is the source.
-AC_CONFIG_FILES(Makefile:m4_defn(`calc_root')/build-aux/Makefile.in
- Makefile.2:m4_defn(`calc_root')/build-aux/Makefile.2.in)
+AC_CONFIG_FILES(Makefile:m4_defn(`calc_root')/build-aux/Makefile.in)
# Generate configure script
AC_OUTPUT
diff --git a/configure.ac b/configure.ac
index a8db59f..f115f9a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,6 +40,7 @@ AC_SUBST(REV, m4_argn(3, ver_split))
AC_SUBST(SUFFIX, m4_argn(4, ver_split))
AC_ARG_VAR([JAVA], [The Java executable])
+AC_ARG_VAR([JAVA_OPTS], [Java options])
AC_CHECK_PROGS(JAVA, [java])
AC_ARG_VAR([SAXON_CP], [Saxon class path])
@@ -52,7 +53,16 @@ AS_IF(test ! -d "$HOXSL",
AC_MSG_ERROR([hoxsl path '$HOXSL' does not exist!]))
AC_MSG_RESULT(found)
+# BC with RATER_CLASSPATH
+DSLC_CLASSPATH="${DSLC_CLASSPATH:-$RATER_CLASSPATH}"
+AC_SUBST(DSLC_CLASSPATH, [$DSLC_CLASSPATH])
+
+AC_SUBST([AUTOGENERATED],
+ ["THIS FILE IS AUTOGENERATED! DO NOT MODIFY! See *.in."])
+
AC_CONFIG_FILES([Makefile doc/Makefile src/init.xsl VERSION])
+AC_CONFIG_FILES([bin/dslc],
+ [chmod +x bin/dslc])
AC_OUTPUT
diff --git a/doc/Makefile.am b/doc/Makefile.am
index fa786d6..9b24485 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -27,7 +27,7 @@ stylesheets := $(shell find "$(path_src)" \
stexi := $(stylesheets:.xsl=.texi)
info_TEXINFOS = tame.texi
-tame_TEXINFOS = todo.texi license.texi $(stexi) tame.css
+tame_TEXINFOS = about.texi todo.texi license.texi $(stexi) tame.css
MAKEINFOHTML=$(MAKEINFO) --html --css-include tame.css
diff --git a/doc/about.texi b/doc/about.texi
new file mode 100644
index 0000000..f4108f7
--- /dev/null
+++ b/doc/about.texi
@@ -0,0 +1,193 @@
+@c This document is part of the TAME manual.
+@c Copyright (C) 2018 R-T Specialty, LLC.
+@c Permission is granted to copy, distribute and/or modify this document
+@c under the terms of the GNU Free Documentation License, Version 1.3 or
+@c any later version published by the Free Software Foundation; with no
+@c Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+@c A copy of the license is included in the section entitled ``GNU Free
+@c Documentation License''.
+
+@node About TAME
+@chapter About TAME
+@tame{} is The Adaptive Metalanguage,
+ a programming language and system of tools designed to aid in the
+ development; understanding; and maintenance of systems performing
+ numerous calculations on a complex graph of dependencies;
+ conditions; and a large number of inputs.
+
+This system was developed at R-T Specialty@footnote{
+ Formerly LoVullo Associates.}
+ to handle the complexity of comparative insurance rating systems.
+It is a domain-specific language@tie{}(DSL) that itself encourages,
+ through the use of templates,
+ the creation of sub-DSLs.
+@tame{} itself is at heart a calculator@mdash{
+ }processing only numerical input and output@mdash{
+ }driven by quantifiers as predicates.
+Calculations and quantifiers are written declaratively without concern
+ for order of execution.
+
+The system has powerful dependency resolution and data flow capabilities.
+
+@tame{} consists of a macro processor (implementing a metalanguage);
+ numerous compilers for various targets
+ (JavaScript, HTML documentation and debugging environment, LaTeX,
+ and others);
+ linkers; and supporting tools.
+The input grammar is XML,
+ and the majority of the project
+ (including the macro processor, compilers, and linkers)
+ is written in XSLT.@footnote{
+ There is a reason for that odd choice;
+ until an explanation is provided,
+ know that someone is perverted enough to implement a full
+ compiler in XSLT.}
+
+
+
+@menu
+* Getting Started:: Getting started from a source repository checkout.
+* Manual Compilation:: How to compile a source file by hand.
+* Compiling With Make:: Using the Makefile (recommended).
+@end menu
+
+
+@node Getting Started
+@section Getting Started
+To get started,
+ make sure Saxon version@tie{}9 or later is available and its path
+ set as @var{SAXON_CP};
+ that the path to hoxsl is set via @var{HOXSL};
+ and then run the @samp{bootstrap} script:
+
+@float Figure, f:bootstrap
+@example
+$ export SAXON_CP=/path/to/saxon9he.jar
+$ export HOXSL=/path/to/hoxsl/root
+
+$ ./boostrap
+@end example
+@caption{Bootstrapping TAME in a source repository checkout}
+@end float
+
+
+
+@node Manual Compilation
+@section Manual Compilation
+@emph{Note: TAME is usually controlled through a Makefile;
+ @pxref{Compiling With Make} to avoid manual compilation
+ steps.}
+
+@tame{} is controlled through the program in @command{bin/tame}.
+When run,
+ it first spawns a daemon @command{bin/tamed} if it is not already
+ running.
+@command{tamed} is needed to keep the JVM and compiled XSLT templates
+ in memory,
+ otherwise each file would incur a steep startup penalty.
+
+@todo{Document commands.
+ Most developers do not build files directly,
+ so this is not essential yet.}
+
+@float Figure, f:compile-ex
+@example
+$ bin/tame compile src/foo.xml src/foo.xmlo
+$ bin/tame link src/foo.xmlo src/foo.xmle
+$ bin/tame standalone src/foo.xmle src/foo.js
+$ bin/tame summary src/foo.xmle src/foo.html
+@end example
+@caption{Compiling a JavaScript executable and Summary Page}
+@end float
+
+To kill the daemon,
+ pass @samp{--kill} to either @file{bin/tame} or @file{bin/tamed}.
+For additional options and environment variables that influence
+ operation,
+ pass @samp{--help} to either command.
+
+
+@node Compiling With Make
+@section Compiling With Make
+TAME can generate a @url{https://gnu.org/software/make,GNU Makefile}
+ for you using @url{https://gnu.org/software/automake,Automake} and
+ @url{https://gnu.org/softeware/autoconf,Autoconf}.
+This greatly simplifies building projects by automatically building
+ all dependencies as needed,
+ and only when they have changed.@footnote{@c
+ When their modification timestamps change, specifically.}
+
+The Makefile is generated by a @file{configure} script,
+ which itself generated by Autoconf using @file{configure.ac} in the
+ project root:
+
+@float Figure, f:configure-ac
+@example
+AC_INIT([PROJECT_NAME], [0.0.0], [contact@@email])
+
+m4_define(`calc_root', rater)
+m4_include([rater/build-aux/m4/calcdsl.m4])
+
+@end example
+@caption{Example @file{configure.ac} in project root.}
+@end float
+
+By convention,
+ TAME is usually available as a submodule under @file{rater/}.
+This confusing naming convention may change in the future.
+
+Then, to generate the @file{Makefile}:
+
+@float Figure, f:configure
+@example
+$ autoreconf -fvi
+$ ./configure SAXON_CP=/path/to/saxon9he.jar
+@end example
+@caption{Invoking @file{configure} to generate @file{Makefile}.}
+@end float
+
+@todo{Add more sections.}
+
+@menu
+* Common Targets:: Common Makefile targets.
+@end menu
+
+
+@node Common Targets
+@subsection Common Targets
+A @dfn{target} is something that can be built.
+Usually it is a specific file (e.g. @file{foo.js}),
+ but it can also be a command (also called a @dfn{phony target}).
+Here are the most common phony targets that may be useful:
+
+@table @samp
+ @item all
+ This is the default target (just type @samp{make}).
+ Build the UI and all suppliers.
+ Does not build the Summary Pages,
+ as they are considered to be debugging tools.
+
+ @item summary-html
+ Build all Summary Pages for programs in @file{suppliers/}.
+ This is equivalent to building each @file{suppliers/*.html} target
+ manually.
+
+ @item check
+ @item test
+ Run test cases in @file{test/}.
+
+ @item standalones
+ Build JavaScript executables for each program in @file{suppliers/}.
+ This is a dependency of @samp{summary-html}.
+
+ @item tamed-die
+ @item kill-tamed
+ Kill running tamed for effective user, if any
+ (@pxref{Manual Compilation}).
+
+ @item clean
+ Delete all file targets.
+ This may be necessary when upgrading TAME,
+ for example,
+ to rebuild all files using the new version.
+@end table
diff --git a/doc/tame.texi b/doc/tame.texi
index 929bac8..b83ddf0 100644
--- a/doc/tame.texi
+++ b/doc/tame.texi
@@ -1,6 +1,6 @@
\input texinfo
@c This document is part of the TAME manual.
-@c Copyright (C) 2015, 2016 R-T Specialty, LLC.
+@c Copyright (C) 2015, 2016, 2018 R-T Specialty, LLC.
@c Permission is granted to copy, distribute and/or modify this document
@c under the terms of the GNU Free Documentation License, Version 1.3 or
@c any later version published by the Free Software Foundation; with no
@@ -19,7 +19,7 @@
@copying
This manual is for TAME, version @value{VERSION}.
-Copyright @copyright{} 2015, 2016 R-T Specialty, LLC.
+Copyright @copyright{} 2015, 2016, 2018 R-T Specialty, LLC.
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -51,6 +51,7 @@ Free Documentation License".
@end ifnottex
@menu
+* About TAME:: History of TAME and how to use it
* Preprocessor:: Metaprogramming system
* Dependency Graph:: Dependency processing and flow analysis
* Symbol Table:: Lookup table for all objects
@@ -97,6 +98,7 @@ TAME
@definfoenclose math,\(,\)
@end ifhtml
+@include about.texi
@node Preprocessor
@chapter Preprocessor
diff --git a/rater/README.md b/rater/README.md
new file mode 100644
index 0000000..a51421e
--- /dev/null
+++ b/rater/README.md
@@ -0,0 +1,6 @@
+# Compatibility Directory
+
+This directory exists for compatibility with earlier build scripts and path
+assumptions before TAME was extracted into its own repository. A full
+transition will remove this directory.
+
diff --git a/rater/c1map b/rater/c1map
new file mode 120000
index 0000000..f63aa7e
--- /dev/null
+++ b/rater/c1map
@@ -0,0 +1 @@
+../src/current/c1map \ No newline at end of file
diff --git a/rater/c1map.xsl b/rater/c1map.xsl
new file mode 120000
index 0000000..e0f281d
--- /dev/null
+++ b/rater/c1map.xsl
@@ -0,0 +1 @@
+../src/current/c1map.xsl \ No newline at end of file
diff --git a/rater/calc.xsd b/rater/calc.xsd
new file mode 120000
index 0000000..ffb2fa9
--- /dev/null
+++ b/rater/calc.xsd
@@ -0,0 +1 @@
+../src/current/calc.xsd \ No newline at end of file
diff --git a/rater/compile.xsl b/rater/compile.xsl
new file mode 120000
index 0000000..d7e1f1d
--- /dev/null
+++ b/rater/compile.xsl
@@ -0,0 +1 @@
+../src/current/compile.xsl \ No newline at end of file
diff --git a/rater/compiler b/rater/compiler
new file mode 120000
index 0000000..b421e27
--- /dev/null
+++ b/rater/compiler
@@ -0,0 +1 @@
+../src/current/compiler \ No newline at end of file
diff --git a/rater/dot.xsl b/rater/dot.xsl
new file mode 120000
index 0000000..9309b8e
--- /dev/null
+++ b/rater/dot.xsl
@@ -0,0 +1 @@
+../src/current/dot.xsl \ No newline at end of file
diff --git a/rater/include b/rater/include
new file mode 120000
index 0000000..5a4e120
--- /dev/null
+++ b/rater/include
@@ -0,0 +1 @@
+../src/current/include/ \ No newline at end of file
diff --git a/rater/link.xsl b/rater/link.xsl
new file mode 120000
index 0000000..392e493
--- /dev/null
+++ b/rater/link.xsl
@@ -0,0 +1 @@
+../src/current/link.xsl \ No newline at end of file
diff --git a/rater/rater.xsd b/rater/rater.xsd
new file mode 100644
index 0000000..d159e2d
--- /dev/null
+++ b/rater/rater.xsd
@@ -0,0 +1,1987 @@
+<?xml version="1.0"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.lovullo.com/rater"
+ xmlns="http://www.lovullo.com/rater"
+ xmlns:c="http://www.lovullo.com/calc"
+ elementFormDefault="qualified">
+
+<!-- this schema supports calculations -->
+<xs:import
+ namespace="http://www.lovullo.com/calc"
+ schemaLocation="calc.xsd" />
+
+<!-- can include maps -->
+<xs:import
+ namespace="http://www.lovullo.com/rater/map"
+ schemaLocation="map.xsd" />
+
+<!-- C1 map -->
+<xs:import
+ namespace="http://www.lovullo.com/rater/map/c1"
+ schemaLocation="c1map.xsd" />
+
+<!-- worksheets -->
+<xs:import
+ namespace="http://www.lovullo.com/rater/worksheet"
+ schemaLocation="worksheet.xsd" />
+
+
+<!--basicTypes-->
+ <xs:simpleType name="packageNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of a package/rater. Must match the name of the XML file, sans the
+ extension. If the package is in a subdirectory, then the name should be
+ a relative path (e.g. "rates/company").
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[a-z][a-z0-9/-]+" />
+ <xs:minLength value="2" />
+ <xs:maxLength value="75" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:simpleType name="constNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of a constant.
+
+ Underscore prefixes should be reserved for system constants.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:NCName">
+ <xs:pattern value="_*[A-Z][A-Z0-9_]+" />
+ <xs:minLength value="1" />
+ <xs:maxLength value="75" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:simpleType name="typeNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of a type (as would be defined via typedef).
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:NCName">
+ <xs:pattern value="[a-zA-Z]+" />
+ <xs:minLength value="1" />
+ <xs:maxLength value="50" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:simpleType name="functionNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of a mathematical function.
+
+ Since the name will appear in equations, it has a restricted character
+ set and length.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:NCName">
+ <xs:pattern value="[a-z_-]+" />
+ <xs:minLength value="1" />
+ <xs:maxLength value="15" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:simpleType name="paramNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of a parameter (global or local)
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:NCName">
+ <xs:pattern value="[a-z_][a-z0-9_]*" />
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:simpleType name="yieldsNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Represents a value yielded by a calculation (e.g. a premium).
+
+ The camelCase requirement as opposed to the snake_case requirement used
+ for other variables, such as params, is intended to provide a
+ distinction.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:pattern value="_*[a-z][a-zA-Z0-9]+|\{?@[a-z][a-zA-Z0-9_]*@\}?" />
+ <xs:minLength value="1" />
+ <xs:maxLength value="50" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:simpleType name="indexNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Single-character index variable
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[a-z]|\{?@[a-z][a-zA-Z0-9_]*@\}?" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:simpleType name="templateNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Template name; underscore prefix and suffix is mandatory to help ensure
+ distinctive names between other identifiers.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:pattern value="_[a-zA-Z0-9@\{\}-]+_" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:simpleType name="templateParamNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Template parameter name
+
+ Template parameters are delimited by '@'s; this restriction is in place
+ to permit substring replacements with clear delimiters.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:pattern value="@[a-z_-][a-zA-Z0-9_-]*@" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:simpleType name="descType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Documentation for a specific element.
+
+ The documentation must not be sparse; please provide something
+ descriptive that will be useful to someone completely new to the code.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <!-- let's make an attempt at reasonable documentation, shall we? -->
+ <xs:minLength value="2" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:simpleType name="symbolType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Symbol used to represent an entity when rendered.
+
+ The string should consist of TeX/LaTeX commands and should produce a
+ single symbol.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string" />
+ </xs:simpleType>
+
+
+ <xs:simpleType name="setType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Types of sets (vectors or matrices)
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="vector" />
+ <xs:enumeration value="matrix" />
+ </xs:restriction>
+ </xs:simpleType>
+<!--/basicTypes-->
+
+
+<!--constants-->
+ <xs:complexType name="itemSetType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Permits the static declaration of a matrix; a set represents a vector
+ and sibling sets can be combined to create a matrix
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <!-- allow an empty set for skipping rows -->
+ <xs:element name="item" type="itemType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+
+ <xs:attribute name="desc" type="descType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Description explaining what the set represents
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+
+ <xs:complexType name="itemType">
+ <xs:attribute name="value" type="xs:token">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Value of the constant; must be compatible with the
+ enumeration's @type.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="desc" type="descType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Description explaining what the value represents
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+
+ <xs:complexType name="constType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Defines a single constant.
+
+ Constants differ from other variables (such as parameters) in that their
+ values cannot change; they exist as an alternative to hard-coding values
+ and as a means of re-use (magic values are not permitted).
+
+ The value of the constant must be compatiable with its type.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:choice>
+ <xs:element name="set" type="itemSetType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="item" type="itemType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:choice>
+
+ <xs:attribute name="name" type="constNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of the constant. The name must always be used in place of the
+ value when referencing the constant.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="value" type="xs:token">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Value of the constant; must be within the domain of its type.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="values" type="xs:token">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Short-hand GNU Octave / MATLAB Style matrix specification.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="type" type="typeNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Constant data type
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="desc" type="descType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Useful description of the constant that explains what it is used for
+ and provides a context
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="sym" type="symbolType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Optional LaTeX symbol for typesetting
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="magic" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ (CORE ONLY) Denotes a constant whose value may be determined by runtime
+
+ This should prevent any compiler from inlining the constant value.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+<!--/constants-->
+
+
+<!--import-->
+ <xs:simpleType name="packagePathType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Path to a package without the extension.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[a-z./][a-zA-Z0-9./-]+" />
+ <xs:minLength value="2" />
+ <xs:maxLength value="100" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:complexType name="topicOfType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Declares the package that this package is a sub-topic of.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="package" type="packagePathType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Path to package, sans the ``.xml'' extension.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="section" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Parent section name; defaults to root.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+
+ <xs:complexType name="importType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Permits importing package or template contents for use in the parent document.
+
+ The @package attribute may be used for explicitly loading a package.
+
+ @templates specifies a path for template auto-loading, but does not load any
+ templates, allowing the system to use only the templates that are needed.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="package" type="packagePathType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Path to package to import, sans the ``.xml'' extension.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="export" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Export the symbols imported by this package
+
+ By default, all imported symbols are local, meaning that importing a
+ package will not include the symbols that the package itself has
+ imported. This is generally desirable from a maintainance standpoint,
+ but certain meta-packages (packages that exist simply to include
+ packages) may wish to make use of this feature.
+
+ Use sparingly.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="topic-of" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Short-hand for a separate topic-of node; parent
+ section. "true" is equivalent to "root".
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="allow-nonpkg" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Allow importing symbol tables that are not explicitly defined as
+ includable packages.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="ignore-keep" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Strip @keep flag from all imported symbols.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="no-extclass" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Do not import symbols flagged as external to the classifier.
+
+ This is of limited use outside of specialized settings, such as the
+ UI classifier.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="keep-classes" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Keep all classifications, even if @ignore-keep is set.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+<!--/import-->
+
+
+<!--typedef-->
+ <xs:complexType name="typedefType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Defines a type that may be used to represent a restricted set of values.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:choice>
+ <xs:element name="union" type="unionType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="enum" type="enumType" minOccurs="0" maxOccurs="1" />
+
+ <!-- used only by core packages -->
+ <xs:element name="base-type" minOccurs="0" maxOccurs="1" />
+ </xs:choice>
+
+ <xs:attribute name="name" type="typeNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name by which the type may be referenced
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="desc" type="descType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Description of what the type may be used for
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="sym" type="symbolType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Optional LaTeX symbol for typesetting
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+
+ <xs:complexType name="unionType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Merges multiple typedefs of the same type into a single type.
+
+ Useful for categorizing types and sub-types in a semantic manner.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:element name="typedef" type="typedefType" minOccurs="2" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+
+ <xs:complexType name="enumType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Defines an enumerated set of values.
+
+ The type may accept any @value in the set. When referenced, @name must
+ be used. The name must be styled as a constant (since it is not a
+ variable).
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:element name="item" minOccurs="1" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="constNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of enumerated value. This defines a constant and so the
+ name should be styled as such.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="value" type="xs:token">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Value of the constant; must be compatible with the
+ enumeration's @type.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="desc" type="descType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Description explaining what the value represents
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+
+ <xs:attribute name="type" type="typeNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Type of all enumerated values in a particular list
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+<!--/typedef-->
+
+
+<!--funcAndParams-->
+ <xs:complexType name="paramType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Represents a parameter accepted by the rater or a function.
+
+ Parameters accepted by the rater itself will be declared globally,
+ whereas parameters defined within functions will be local to that
+ function.
+
+ Regardless of scope, parameter names must never conflict.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="name" type="paramNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name by which parameter can be identified
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="type" type="typeNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Parameter data type
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="desc" type="descType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Description of parameter
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="set" type="setType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Whether or not the parameter is a set of values of type @type (an
+ array)
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="default" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Default value for parameter if none is provided; must be within the
+ domain of its @type
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="sym" type="symbolType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Optional LaTeX symbol for typesetting
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+
+ <xs:complexType name="functionType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Defines a mathematical function --- a reusable equation that optionally
+ accepts arguments.
+
+ Functions also have access to the global argument list and any other
+ values; not everything must be passed in. Functions may contain only
+ a single calculation node (which itself may contain other calculations).
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:group ref="c:calculationRoot" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+
+ <xs:attribute name="name" type="functionNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of the function. Since the function is intended to be a function
+ in the mathematical sense and may be output as part of an equation,
+ the name is restricted to lowercase alpha characters.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="desc" type="descType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Description of function and its purpose
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="sym" type="symbolType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Optional symbol to use in place of function name when typesetting
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+<!--/funcAndParams-->
+
+
+<!--rate-->
+ <xs:simpleType name="classType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ String of classifications, space-delimited.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:token">
+ <xs:pattern value="([a-z-][a-z0-9-]+ ?)+|@[a-z][a-zA-Z0-9_]*@" />
+ <xs:minLength value="1" />
+ <xs:maxLength value="100" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+
+ <!-- name derived from xsl:with-param; distinguishes between macro params and
+ lv:arg -->
+ <xs:complexType name="withParamType">
+ <xs:sequence>
+ <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+ </xs:sequence>
+
+ <xs:attribute name="name" type="templateParamNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of parameter to replace in template
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="value" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ String with which template parameter should be replaced
+
+ All template parameters are replaced by the preprocessor before
+ the XML document reaches any other system; this means that all
+ parameter replacements are performed as strings, just as if you
+ copied and pasted the template XML into place and did a
+ search-and-replace/regex on the XML.
+
+ Consequently, variable replacements are not permitted. You may
+ replace the parameter with text representing the name of a
+ global parameter, for example, but you cannot pass in the
+ current value of of that parameter.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+
+ <xs:complexType name="applyTemplateType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ This node will be entirely removed and replaced with the child nodes
+ of the referenced template.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:element name="with-param" type="withParamType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+
+ <xs:attribute name="name" type="templateNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of template to include in its place.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <!-- any other attributes will be expanded into lv:with-param; this works
+ well since macros work with string values -->
+ <xs:anyAttribute namespace="##any" processContents="lax" />
+ </xs:complexType>
+
+
+ <xs:complexType name="inlineTemplateType" mixed="true">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ This node will be replaced with the processed template.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:element name="for-each" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="sym-set" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:anyAttribute namespace="##any" processContents="lax" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="set" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:anyAttribute namespace="##any" processContents="lax" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <!-- see also templateType -->
+ <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+ </xs:sequence>
+ </xs:complexType>
+
+
+ <xs:group name="calcOrTemplate">
+ <xs:choice>
+ <!-- long-hand -->
+ <xs:element name="apply-template" type="applyTemplateType" />
+ <xs:element name="inline-template" type="inlineTemplateType" />
+
+ <!-- short-hand with namespace prefix -->
+ <xs:any namespace="http://www.lovullo.com/rater/apply-template"
+ minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+
+ <xs:group ref="c:calculationRoot" />
+ </xs:choice>
+ </xs:group>
+
+
+ <xs:complexType name="rateCommon" abstract="true">
+ <xs:attribute name="class" type="classType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Classifications, delimited by spaces, that must be satisfied in order
+ to perform the premium calculation.
+
+ If no classification is given, then the rating will always be
+ performed.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="no" type="classType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Classifications, delimited by commas, that must be <em>not</em> be
+ satisfied in order to perform the premium calculation.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="sym" type="symbolType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Optional LaTeX symbol used to identify this premium (display only)
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="always" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Always enter this rate block, even if the classification does not
+ match. This is useful if you wish to use the _CMATCH_ results
+ even on a non-match.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+
+ <!-- alternative to @class -->
+ <xs:complexType name="classNodeType">
+ <xs:attribute name="ref" type="classNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Class name to apply to block
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="no" type="xs:boolean" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Whether or not the classification should be considered as if it were
+ part of a @no attribute
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+
+ <xs:complexType name="rateTypeSansYields">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Represents a premium calculation to be performed based on a prior
+ classification (sans @yields)
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:complexContent>
+ <xs:extension base="rateCommon">
+ <xs:sequence>
+ <xs:element name="class" type="classNodeType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:group ref="calcOrTemplate" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+
+ <xs:attribute name="precision" type="constNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Precision of result (empty will use system default)
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="keep" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Compile the rate block even if it does not contribute to the
+ final premium (that is---is outside the dependency tree of
+ lv:yields)
+
+ This is useful for calculating supplemental data that does not
+ directly contribute to the premium.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="external" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Rate calculation should be compiled external to the classifier (that
+ is, the classification should only be performed on-demand for rating
+ purposes).
+
+ This has the benefit of removing the classifier from the classify()
+ method, which may be important for, say, asserting on final premium
+ amount.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+
+ <xs:complexType name="rateType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Represents a premium calculation to be performed based on a prior
+ classification
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:complexContent>
+ <xs:extension base="rateTypeSansYields">
+ <xs:attribute name="yields" type="yieldsNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Variable in which to store the result of the calculation (will
+ default to 0 if calculation is not performed).
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+
+ <xs:complexType name="rateEachType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Identical to lv:rate, except that it requires and index with which it
+ will automatically loop through the magic _CMATCH_ set and multiply the
+ calculation by its value; this creates a conditional effect.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:complexContent>
+ <xs:extension base="rateTypeSansYields">
+ <xs:attribute name="index" type="indexNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Set the index to use for summing over the _CMATCH_ set.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="yields" type="yieldsNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Optional variable in which to store the result of the calculation (will
+ default to 0 if calculation is not performed).
+
+ If not provided, will prefix the value of @generates.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="generates" type="yieldsNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Produces a generating function as vector @generates
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="gensym" type="symbolType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Symbol to use for display of generator
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="dim" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Number of dimensions as integer or alias.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+
+ <xs:complexType name="rateEachTemplateType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Generates lv:rate-each, applying the given template (simply removes
+ boilerplate template application at the root level)
+
+ The template is expected to accept an @index@ parameter.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:complexContent>
+ <xs:extension base="rateCommon">
+ <xs:sequence>
+ <xs:element name="class" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="ref" type="classNameType" use="required" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="with-param" type="withParamType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+
+ <xs:attribute name="name" type="templateNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Template to apply
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="yields" type="yieldsNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Variable in which to store the result of the calculation (will
+ default to 0 if calculation is not performed).
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="generates">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Produces a generating function as vector @generates
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="gensym" type="symbolType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Symbol to use for display of generator
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="keep" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Compile the rate block even if it does not contribute to the
+ final premium (that is---is outside the dependency tree of
+ lv:yields)
+
+ This is useful for calculating supplemental data that does not
+ directly contribute to the premium.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="local" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ The symbol associated with the rate block should never be exported
+ (similar to a private member in Object-Oriented languages, or
+ static definitions in C)
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+
+ <xs:group name="templateParamGenGroup">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Permits default value generation.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:choice>
+ <xs:element name="text">
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="unique" type="xs:boolean" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="param-value">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string" use="required" />
+
+ <xs:attribute name="ucfirst" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Converts the first character of the value to uppercase
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="upper" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Converts the string to uppercase
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="lower" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Converts the string to lowercase
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="snake" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Converts '-' to '_'
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="rmdash" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Converts '-' to ''
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="dash" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Converts spaces to dashes
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="identifier" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Strip all characters that do not constitute a valid
+ object identifier (for use in genrating names)
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="param-inherit">
+ <xs:complexType>
+ <xs:attribute name="meta" type="xs:string" use="required" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="param-add">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string" use="required" />
+
+ <xs:attribute name="value" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Value to add to param (assumed to be a numeric param)
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="param-class-to-yields">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Converts a class name to its @yields variable
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string" use="required" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="param-sym-value">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Retrieve symbol metadata.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:anyAttribute namespace="##any" processContents="lax" />
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+ </xs:group>
+
+
+ <xs:element name="param-copy">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="param-meta" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:attribute name="value" type="xs:string" use="required" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+
+ <xs:attribute name="name" type="xs:string" use="required" />
+
+ <xs:attribute name="expand" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Result of param copy should trigger template param expansion has if
+ the copied nodes were a part of the template itself.
+
+ Without this option, param expansion is not performed on the copied
+ nodes for that pass, meaning that the copied nodes will be
+ unaffected by the template.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+
+ <!-- TODO: if -->
+ <xs:element name="unless">
+ <xs:complexType mixed="true">
+ <xs:sequence>
+ <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+ </xs:sequence>
+
+ <xs:anyAttribute namespace="##any" processContents="lax" />
+ </xs:complexType>
+ </xs:element>
+
+
+ <xs:complexType name="templateParamType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Declares a parameter available for replacement within the template.
+
+ Notice how, unlike parameters for raters and functions, this parameter
+ does not require a type; this is because all replacements are done by
+ the preprocessor and, as such, all replacements are done as strings.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:group ref="templateParamGenGroup" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+
+ <xs:attribute name="name" type="templateParamNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Parameter name to be used for replacements
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="desc" type="descType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Parameter description
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+
+ <xs:complexType name="templateType" mixed="true">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Declares a template whose body may be referenced using lv:apply-template.
+
+ Templates are a basic means of code reuse that act as macros: when
+ referenced by lv:apply-template, the body of the template will be put
+ in its place as if it were pasted by hand. Therefore, this achieves the
+ effect of copy-and-paste without the obvious downsides of actually
+ copying and pasting code.
+
+ This permits the construction of lv:rate blocks in a more natural manner. Other
+ methods of re-use include referencing previously calculated premiums (by other
+ lv:rate blocks) and the use of functions; both have their downsides. Namely:
+
+ - Premiums calculated by other lv:rate blocks yield a single float value, which
+ aggregates individual indexes that may have been used during rating. As such,
+ if you need those individual premiums per index, premiums from other lv:rate
+ blocks cannot be used. In such a case, functions may be used.
+ - Using a function requires verbose code for application and makes
+ the documentation and debugging more complicated. It does, however,
+ have the benefit of being able to accept arguments, which templates
+ cannot do (and as such should be used whenever variable reuse is
+ necessary outside the scope of the global parameter list).
+ - Templates were designed with the idea that a bunch of common calculations
+ could be defined that could then be applied to individual raters as a more
+ natural alternative to functions. That is---the developer is accustomed to
+ creating lv:rate blocks that contain calculations, not excessive function
+ calls joined together with other expressions. Templates eliminate the need
+ for boilerplate function application code and, because they are handled by
+ the preprocessor, also generate easy-to-understand documentation and make
+ debugging more natural for both developers and testers.
+ - While templates do not accept arguments, they *do* permit string-replacement
+ of parameters by the preprocessor. This has the benefit of being
+ able to replace text as if it were done in your editor.
+ Consequently, this means that the replacement can be anything that
+ is considered valid by the validator/compiler.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:element name="param" type="templateParamType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+ </xs:sequence>
+
+ <xs:attribute name="name" type="templateNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Template name; will be used by lv:apply-template.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="desc" type="descType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Describe purpose of the template
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+<!--/rate-->
+
+
+<!--classify-->
+ <xs:simpleType name="classNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Classification identifier; will be used to refer to the classification.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[a-z-][a-z0-9-]+|@[a-z][a-zA-Z0-9_]*@" />
+ <xs:minLength value="2" />
+ <xs:maxLength value="50" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:complexType name="classifyType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Classifies data based on the provided argument list and other
+ classifications. Classifications are used during rating to determine
+ how premiums should be calculated in a declarative manner.
+
+ If no classification criteria are provided, then the classification
+ will always take place (implying a direct "is a" relationship between
+ the rater and a particular classification).
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:group ref="classCriteria" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+
+ <xs:attribute name="as" type="classNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of classification. Can be used to determine whether or not the
+ data has been classified as such.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="any" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Convert classification from a universal quantifier into an
+ existential
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="desc" type="descType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Description of classification
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="yields" type="yieldsNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Optional variable in which to store a boolean set of matches (useful
+ if classifying against sets)
+
+ As an example, consider classifying as vacant land by matching on a
+ set of class codes. The system will check each class code in the
+ provided set against valid class codes for vacant land. Should one
+ item in the set match <em>any</em> of the criteria, the
+ classification will succeed and its associated index in the @yields
+ identifier will be set to 1. Otherwise, the value will remain 0.
+
+ This allows for performing conditional calculations by simply
+ multiplying by the boolean value. If the value is 0, that portion of
+ the equation will effectively have not happened, simulating a
+ conditional.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="keep" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Always perform the classification, even if it is unused.
+
+ Otherwise, the system may not compile unused classifications (and so
+ the classification would not occur).
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="terminate" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Classification should result in termination (useful for eligibility
+ and error conditions)
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="external" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Classification should be compiled external to the classifier (that
+ is, the classification should only be performed on-demand for rating
+ purposes).
+
+ This has the benefit of removing the classifier from the classify()
+ method, which may be important for, say, asserting on final premium
+ amount.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+
+ <xs:group name="classCriteria">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Criteria with which a classification may be matched.
+
+ All criteria is driven off of the global argument list.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:choice>
+ <xs:group ref="applyTemplateGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="any" type="anyMatchType" />
+ <xs:element name="match" type="matchType" />
+ <xs:element name="join" type="joinMatchType" />
+ <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+ </xs:choice>
+ </xs:group>
+
+
+ <xs:complexType name="anyMatchType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Succeeds if any of the child matches succeed (equivalent to an OR statement).
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:group ref="anyMatchNodes" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:group name="anyMatchNodes">
+ <xs:choice>
+ <xs:group ref="classCriteria" minOccurs="1" maxOccurs="unbounded" />
+ <xs:element name="all" type="allMatchType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+ </xs:choice>
+ </xs:group>
+
+
+ <xs:complexType name="allMatchType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Succeeds if all of the child matches succeed (equivalent to an AND statement).
+
+ This is implied by the root lv:classify node.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:group ref="classCriteria" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+
+ <xs:complexType name="matchType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Perform a basic match against a given value or enumerated list.
+
+ One of value or anyOf should be provided. If neither is provided, one
+ may provide any condition nodes accepted by c:when; multiple will be
+ combined with logical and. This provides additional flexibility
+ necessary for more complicated assertions that would otherwise rely on
+ convoluted regular expressions.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:group ref="c:conditions" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+
+ <xs:attribute name="on" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Name of global parameter to perform match on
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="value" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Value to match against (must be within domain of parameter). Use only
+ one of this or @anyOf.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="anyOf" type="typeNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Value must match any value within an enumerated list. Enumeration to
+ match against must be within the domain of the parameter. USe only
+ one of this or @value.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="pattern" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ JavaScript-compatible regular expression
+
+ Forward slashes must be escaped with a backslash and opening/closing
+ delimiters should not be specified.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+
+ <xs:complexType name="joinMatchType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Join matching classifiers into an lv:any block where they will be
+ matched on the value TRUE.
+
+ Each matching classifier must have a @yields attribute.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="prefix" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Any classifier's @as attribute matching this prefix will be included
+ within an lv:any block.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="all" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Univerisal quantifier (default is existential)
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+<!--/classify-->
+
+
+<xs:complexType name="yieldType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Yields a single value (premium) representing the entire result of the
+ rating process.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:group ref="c:calculationRoot" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+</xs:complexType>
+
+
+<!--extern-->
+ <xs:simpleType name="externSymbolTypes">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Internal symbol types
+
+ These are the strings used directly by the symbol map; it is
+ recommended that the user use some type of abstraction (e.g. a
+ template).
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="rate" />
+ <xs:enumeration value="gen" />
+ <xs:enumeration value="cgen" />
+ <xs:enumeration value="param" />
+ <xs:enumeration value="lparam" />
+ <xs:enumeration value="const" />
+ <xs:enumeration value="tpl" />
+ <xs:enumeration value="type" />
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:complexType name="externType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Declares an external symbol
+
+ This allows a symbol to be used in a package that does not either include
+ or define it. The symbol must be defined before linking.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="name" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Symbol name
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="type" type="externSymbolTypes" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Symbol type
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="dtype" type="typeNameType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Symbol data type
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="dim" type="xs:integer" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Symbol dimensions (0 = scalar, 1 = vector, 2 = matrix, etc)
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="missing" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Optional user-friendly message to output when extern is
+ missing (such as how to satisfy it).
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+<!--/extern-->
+
+
+<xs:element name="packageBase" type="packageBaseType" abstract="true">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Represents a single rater (calculator). This is a root node; there may be
+ only one rater per document.
+ </xs:documentation>
+ </xs:annotation>
+</xs:element>
+
+
+<xs:group name="sectionGroupRoot">
+ <xs:choice>
+ <xs:group ref="rateGroup" minOccurs="0" maxOccurs="unbounded" />
+
+ <xs:element name="section">
+ <xs:complexType mixed="true">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Denotes a group of common data. The section title will
+ become a heading in the documentation.
+ </xs:documentation>
+ </xs:annotation>
+
+ <!-- XXX: duplicated -->
+ <xs:choice maxOccurs="unbounded">
+ <xs:group ref="importGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="extern" type="externType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="meta" type="metaType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="typedef" type="typedefType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="const" type="constType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:group ref="classifyGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xs:group ref="functionGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xs:group ref="sectionGroupRoot" minOccurs="0" maxOccurs="unbounded" />
+ </xs:choice>
+
+ <xs:attribute name="title" type="descType" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Section title to appear in documentation.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+</xs:group>
+
+
+<xs:group name="applyTemplateGroup">
+ <xs:choice>
+ <!-- any of the below can be enclosed within a template -->
+ <xs:element name="apply-template" type="applyTemplateType" />
+ <xs:element name="inline-template" type="inlineTemplateType" />
+
+ <!-- short-hand with namespace prefix -->
+ <xs:any namespace="http://www.lovullo.com/rater/apply-template"
+ minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+ </xs:choice>
+</xs:group>
+
+<xs:group name="importGroup">
+ <xs:choice>
+ <xs:element name="topic-of" type="topicOfType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="import" type="importType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:group ref="applyTemplateGroup" minOccurs="0" maxOccurs="unbounded" />
+ </xs:choice>
+</xs:group>
+
+<xs:group name="rateGroup">
+ <xs:choice>
+ <xs:group ref="applyTemplateGroup" minOccurs="0" maxOccurs="unbounded" />
+
+ <xs:element name="rate" type="rateType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="rate-each" type="rateEachType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="rate-each-template" type="rateEachTemplateType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="template" type="templateType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:choice>
+</xs:group>
+
+<xs:group name="functionGroup">
+ <xs:choice>
+ <xs:element name="function" type="functionType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="template" type="templateType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:choice>
+</xs:group>
+
+<xs:group name="classifyGroup">
+ <xs:choice>
+ <xs:element name="classify" type="classifyType" minOccurs="0" />
+ <xs:element name="apply-template" type="applyTemplateType" minOccurs="0" />
+ <xs:element name="inline-template" type="inlineTemplateType" minOccurs="0" />
+ <xs:any namespace="http://www.lovullo.com/rater/apply-template" processContents="lax" minOccurs="0" />
+ </xs:choice>
+</xs:group>
+
+
+<xs:complexType name="metaType">
+ <xs:sequence>
+ <xs:element name="prop" minOccurs="1" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="value" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="constNameType" use="required" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="const" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="value" type="xs:string" use="required" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+
+ <xs:attribute name="name" type="xs:string" use="required" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+</xs:complexType>
+
+
+<xs:complexType name="packageBaseType" abstract="true"
+ mixed="true">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Base type that defines elements and attributes acceptable by any package
+ (note that a rater is considered to be a concrete package).
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:choice maxOccurs="unbounded">
+ <xs:group ref="importGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="extern" type="externType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="meta" type="metaType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="const" type="constType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="typedef" type="typedefType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:group ref="classifyGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xs:group ref="functionGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xs:group ref="sectionGroupRoot" minOccurs="0" maxOccurs="unbounded" />
+
+ <!-- intended for code generators -->
+ <xs:element name="__external-data" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="yield" type="yieldType" minOccurs="0" maxOccurs="1">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Entry point for a program package; yields final result.
+
+ This will result in an error if the package is not a program.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+
+ <!-- with how dynamic the system is, maintaining this XSD is becoming
+ cumbersome; we need to generate one -->
+ <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+ </xs:choice>
+
+ <xs:attribute name="name" type="packageNameType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ UNIX-style package name that may be used to identify the package. Must
+ match the name of the file, sans the ``.xml'' extension.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+</xs:complexType>
+
+
+<xs:element name="rater">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Represents a single rater (calculator). This is a root node; there may be
+ only one rater per document. All raters yield a final premium.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:extension base="packageBaseType" />
+ </xs:complexContent>
+ </xs:complexType>
+</xs:element>
+
+
+<xs:element name="package">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Represents a reusable package that may be included in raters or other
+ packages. This is a root node; there may be only one per document.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:extension base="packageBaseType">
+ <!-- TODO: make required after @desc is removed -->
+ <xs:attribute name="title" type="descType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Package title. This is used as a user-friendly package
+ name, and as the heading for generated documentation.
+
+ This replaces the previous <tt>@desc</tt> attribute,
+ which existed prior to the literate implementation.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="desc" type="descType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Deprecated; use @title.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="program" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Package contains an entry point can may be linked into an
+ executable.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <!-- used only by core packages -->
+ <xs:attribute name="core" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Used to indicate that the package is contained within the rating
+ framework itself. <strong>Do not use for your own
+ packages.</strong>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="debug" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Setting this to "true" will enable pretty sweet debugging features that
+ will make your life more tolerable (and perhaps even pleasant).
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="no-extclass-keeps" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ When importing @keep symbols from packages, ignore those flagged
+ as @extclass
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="auto-keep-imports" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Automatically treat all symbols as if they had @keep set.
+
+ This ensures that all imported symbols will be present in
+ the compiled output. This is generally not desired, since
+ it will inflate the output by including unused symbols.
+
+ N.B.: Currently only keeps classifications and their
+ generators!
+
+ This is of limited use outside of specialized settings, such
+ as the UI classifier.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+
+ <xs:attribute name="keep-elig-class" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Mark generated eligibility classification with @keep.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+</xs:element>
+
+
+<xs:element name="template" type="templateType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Templates may exist as the root node in their own file for auto-loading.
+ </xs:documentation>
+ </xs:annotation>
+</xs:element>
+
+</xs:schema>
diff --git a/rater/standalone.xsl b/rater/standalone.xsl
new file mode 120000
index 0000000..bda2787
--- /dev/null
+++ b/rater/standalone.xsl
@@ -0,0 +1 @@
+../src/current/standalone.xsl \ No newline at end of file
diff --git a/rater/summary.xsl b/rater/summary.xsl
new file mode 120000
index 0000000..fc558d7
--- /dev/null
+++ b/rater/summary.xsl
@@ -0,0 +1 @@
+../src/current/summary.xsl \ No newline at end of file
diff --git a/rater/tame b/rater/tame
new file mode 120000
index 0000000..b870225
--- /dev/null
+++ b/rater/tame
@@ -0,0 +1 @@
+../ \ No newline at end of file
diff --git a/src/current/include/preproc/template.xsl b/src/current/include/preproc/template.xsl
index bc63fe6..0f6e64d 100644
--- a/src/current/include/preproc/template.xsl
+++ b/src/current/include/preproc/template.xsl
@@ -1380,8 +1380,7 @@
-<xsl:function name="eseq:expand-node" as="node()*"
- override="yes">
+<xsl:function name="eseq:expand-node" as="node()*">
<xsl:param name="node" as="node()" />
<xsl:apply-templates mode="preproc:macros"
diff --git a/src/current/src/Makefile b/src/current/src/Makefile
index 2b9d08e..08fbd0a 100644
--- a/src/current/src/Makefile
+++ b/src/current/src/Makefile
@@ -2,8 +2,9 @@
dslc_src := $(wildcard com/lovullo/dslc/*.java)
dslc_bin := $(dslc_src:.java=.class)
-.PHONY: dslc clean
+.PHONY: all all-nodoc dslc clean
+all: dslc
dslc: dslc.jar
%.class: %.java
diff --git a/src/current/src/com/lovullo/dslc/DslCompiler.java b/src/current/src/com/lovullo/dslc/DslCompiler.java
index 0c33abf..2f51945 100644
--- a/src/current/src/com/lovullo/dslc/DslCompiler.java
+++ b/src/current/src/com/lovullo/dslc/DslCompiler.java
@@ -69,17 +69,10 @@ public class DslCompiler
HashMap<String,String> params
) throws Exception
{
- if ( cmd.equals( "validate" ) )
+ // validate before compilation
+ if ( cmd.equals( "compile" ) )
{
_xsd.validate( doc );
- return;
- }
- else if ( cmd.equals( "rm" ) )
- {
- // remove file (purposely uncaught)
- ( new File( src ) ).delete();
-
- return;
}
if ( dest.equals( "" ) )
@@ -105,12 +98,17 @@ public class DslCompiler
new StreamResult( new File( dest ) ),
params
);
+
+ // TODO: more unique identifier
+ System.err.println( "DONE 0 " + dest );
}
catch ( Exception e )
{
// delete the output file; it's garbage
destfile.delete();
+ System.err.println( "DONE 1 " + dest );
+
// be verbose and unprofessional.
throw e;
}
@@ -290,7 +288,8 @@ public class DslCompiler
private static void compileSrc( _DslCompiler dslc, String cmdline ) throws Exception
{
- System.err.println( cmdline );
+ System.err.printf( "COMMAND " + cmdline + "\n" );
+
String[] args = cmdline.split( " " );
String dest = "";