aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/manual.tex1
-rw-r--r--src/compiler.sig1
-rw-r--r--src/compiler.sml15
-rw-r--r--src/demo.sml7
-rw-r--r--src/settings.sig1
-rw-r--r--src/settings.sml12
6 files changed, 30 insertions, 7 deletions
diff --git a/doc/manual.tex b/doc/manual.tex
index f6d67f07..3d73b948 100644
--- a/doc/manual.tex
+++ b/doc/manual.tex
@@ -155,6 +155,7 @@ Here is the complete list of directive forms. ``FFI'' stands for ``foreign func
\item \texttt{include FILENAME} adds \texttt{FILENAME} to the list of files to be \texttt{\#include}d in C sources. This is most useful for interfacing with new FFI modules.
\item \texttt{jsFile FILENAME} asks to serve the contents of a file as JavaScript. All such content is concatenated into a single file, included via a \texttt{<script>} tag on every page that needs client-side scripting.
\item \texttt{jsFunc Module.ident=name} gives the JavaScript name of an FFI value.
+\item \texttt{jsModule Module} helps make \texttt{jsFunc} directives less verbose, by setting a module name to prefix in front of \texttt{name} arguments (so running e.g. \texttt{jsFunc MyFfi.foo=bar} actually sets up \texttt{Mod.bar} as the JavaScript name for that function, if \texttt{jsModule Mod} was run beforehand).
\item \texttt{library FILENAME} parses \texttt{FILENAME.urp} and merges its contents with the rest of the current file's contents. If \texttt{FILENAME.urp} doesn't exist, the compiler also tries \texttt{FILENAME/lib.urp}.
\item \texttt{limit class num} sets a resource usage limit for generated applications. The limit \texttt{class} will be set to the non-negative integer \texttt{num}. The classes are:
\begin{itemize}
diff --git a/src/compiler.sig b/src/compiler.sig
index a4b3e562..952c7070 100644
--- a/src/compiler.sig
+++ b/src/compiler.sig
@@ -48,6 +48,7 @@ signature COMPILER = sig
benignEffectful : Settings.ffi list,
clientOnly : Settings.ffi list,
serverOnly : Settings.ffi list,
+ jsModule : string option,
jsFuncs : (Settings.ffi * string) list,
rewrites : Settings.rewrite list,
filterUrl : Settings.rule list,
diff --git a/src/compiler.sml b/src/compiler.sml
index 3e08fcc6..c13de304 100644
--- a/src/compiler.sml
+++ b/src/compiler.sml
@@ -52,6 +52,7 @@ type job = {
benignEffectful : Settings.ffi list,
clientOnly : Settings.ffi list,
serverOnly : Settings.ffi list,
+ jsModule : string option,
jsFuncs : (Settings.ffi * string) list,
rewrites : Settings.rewrite list,
filterUrl : Settings.rule list,
@@ -273,7 +274,7 @@ val parseUr = {
fun p_job ({prefix, database, exe, sql, sources, debug, profile,
timeout, ffi, link, headers, scripts,
- clientToServer, effectful, benignEffectful, clientOnly, serverOnly, jsFuncs, ...} : job) =
+ clientToServer, effectful, benignEffectful, clientOnly, serverOnly, jsModule, jsFuncs, ...} : job) =
let
open Print.PD
open Print
@@ -312,6 +313,9 @@ fun p_job ({prefix, database, exe, sql, sources, debug, profile,
p_ffi "BenignEffectful" benignEffectful,
p_ffi "ClientOnly" clientOnly,
p_ffi "ServerOnly" serverOnly,
+ case jsModule of
+ NONE => string "No JavaScript FFI module"
+ | SOME m => string ("JavaScript FFI module: " ^ m),
p_list_sep (box []) (fn ((m, s), s') =>
box [string "JsFunc", space, string m, string ".", string s,
space, string "=", space, string s', newline]) jsFuncs,
@@ -368,6 +372,7 @@ fun institutionalizeJob (job : job) =
Settings.setBenignEffectful (#benignEffectful job);
Settings.setClientOnly (#clientOnly job);
Settings.setServerOnly (#serverOnly job);
+ Settings.setJsModule (#jsModule job);
Settings.setJsFuncs (#jsFuncs job);
Settings.setRewriteRules (#rewrites job);
Settings.setUrlRules (#filterUrl job);
@@ -445,6 +450,7 @@ fun parseUrp' accLibs fname =
benignEffectful = [],
clientOnly = [],
serverOnly = [],
+ jsModule = NONE,
jsFuncs = [],
rewrites = [{pkind = Settings.Any,
kind = Settings.Prefix,
@@ -579,6 +585,7 @@ fun parseUrp' accLibs fname =
val benignEffectful = ref []
val clientOnly = ref []
val serverOnly = ref []
+ val jsModule = ref NONE
val jsFuncs = ref []
val rewrites = ref []
val url = ref []
@@ -616,6 +623,7 @@ fun parseUrp' accLibs fname =
benignEffectful = rev (!benignEffectful),
clientOnly = rev (!clientOnly),
serverOnly = rev (!serverOnly),
+ jsModule = !jsModule,
jsFuncs = rev (!jsFuncs),
rewrites = rev (!rewrites),
filterUrl = rev (!url),
@@ -674,6 +682,7 @@ fun parseUrp' accLibs fname =
benignEffectful = #benignEffectful old @ #benignEffectful new,
clientOnly = #clientOnly old @ #clientOnly new,
serverOnly = #serverOnly old @ #serverOnly new,
+ jsModule = #jsModule old,
jsFuncs = #jsFuncs old @ #jsFuncs new,
rewrites = #rewrites old @ #rewrites new,
filterUrl = #filterUrl old @ #filterUrl new,
@@ -809,6 +818,10 @@ fun parseUrp' accLibs fname =
| "benignEffectful" => benignEffectful := ffiS () :: !benignEffectful
| "clientOnly" => clientOnly := ffiS () :: !clientOnly
| "serverOnly" => serverOnly := ffiS () :: !serverOnly
+ | "jsModule" =>
+ (case !jsModule of
+ NONE => jsModule := SOME arg
+ | SOME _ => ())
| "jsFunc" => jsFuncs := ffiM () :: !jsFuncs
| "rewrite" =>
let
diff --git a/src/demo.sml b/src/demo.sml
index 47d22395..62b9037a 100644
--- a/src/demo.sml
+++ b/src/demo.sml
@@ -16,7 +16,7 @@
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
@@ -111,6 +111,7 @@ fun make' {prefix, dirname, guided} =
benignEffectful = [],
clientOnly = [],
serverOnly = [],
+ jsModule = NONE,
jsFuncs = [],
rewrites = #rewrites combined @ #rewrites urp,
filterUrl = #filterUrl combined @ #filterUrl urp,
@@ -280,7 +281,7 @@ fun make' {prefix, dirname, guided} =
val (urpData, out) = startUrp urp
in
finished ();
-
+
SOME (readUrp (urpData,
out))
end
@@ -399,7 +400,7 @@ fun make' {prefix, dirname, guided} =
case #kind rule of
Settings.Exact => ()
| Settings.Prefix => TextIO.output (outf, "*");
- TextIO.output (outf, "\n")))
+ TextIO.output (outf, "\n")))
in
Option.app (fn db => (TextIO.output (outf, "database ");
TextIO.output (outf, db);
diff --git a/src/settings.sig b/src/settings.sig
index 0ae81b13..256a12b5 100644
--- a/src/settings.sig
+++ b/src/settings.sig
@@ -96,6 +96,7 @@ signature SETTINGS = sig
val isServerOnly : ffi -> bool
(* Which FFI functions may be run in JavaScript? (JavaScript function names included) *)
+ val setJsModule : string option -> unit
val setJsFuncs : (ffi * string) list -> unit
val addJsFunc : ffi * string -> unit
val jsFunc : ffi -> string option
diff --git a/src/settings.sml b/src/settings.sml
index 9fdc2232..7ae4bf85 100644
--- a/src/settings.sml
+++ b/src/settings.sml
@@ -346,7 +346,7 @@ val jsFuncsBase = basisM [("alert", "alert"),
("asin", "asin"),
("acos", "acos"),
("atan", "atan"),
- ("atan2", "atan2"),
+ ("atan2", "atan2"),
("abs", "abs"),
("now", "now"),
@@ -395,9 +395,15 @@ val jsFuncsBase = basisM [("alert", "alert"),
("htmlifySpecialChar", "htmlifySpecialChar"),
("chr", "chr")]
val jsFuncs = ref jsFuncsBase
-fun setJsFuncs ls = jsFuncs := foldl (fn ((k, v), m) => M.insert (m, k, v)) jsFuncsBase ls
+val jsModule = ref NONE
+fun setJsModule m = jsModule := m
+fun jsFuncName f =
+ case !jsModule of
+ SOME m => m ^ "." ^ f
+ | NONE => f
+fun setJsFuncs ls = jsFuncs := foldl (fn ((k, v), m) => M.insert (m, k, jsFuncName v)) jsFuncsBase ls
fun jsFunc x = M.find (!jsFuncs, x)
-fun addJsFunc (k, v) = jsFuncs := M.insert (!jsFuncs, k, v)
+fun addJsFunc (k, v) = jsFuncs := M.insert (!jsFuncs, k, jsFuncName v)
fun allJsFuncs () = M.listItemsi (!jsFuncs)
datatype pattern_kind = Exact | Prefix