Index: trunk/FACT++/src/InterpreterV8.cc
===================================================================
--- trunk/FACT++/src/InterpreterV8.cc	(revision 14602)
+++ trunk/FACT++/src/InterpreterV8.cc	(revision 14603)
@@ -19,4 +19,6 @@
 
 #include <v8.h>
+
+#include "tools.h"
 
 using namespace std;
@@ -117,5 +119,5 @@
     HandleScope handle_scope;
 
-    const Handle<Script> script = Script::Compile(String::New(code.c_str()));
+    const Handle<Script> script = Script::Compile(String::New(code.c_str()), String::New("internal"));
     if (script.IsEmpty())
         return Undefined();
@@ -140,5 +142,5 @@
     TryCatch exception;
 
-    const Handle<Script> sleep = Script::Compile(String::New(("dim.sleep("+to_string(ms)+");").c_str()));
+    const Handle<Script> sleep = Script::Compile(String::New(("dim.sleep("+to_string(ms)+");").c_str()), String::New("internal"));
     if (ms==0 || (!sleep.IsEmpty() && !sleep->Run().IsEmpty()))
     {
@@ -249,5 +251,5 @@
                       "{"
                          "var s = dim.state(name);"
-                         "if(!"+index+")throw 'Waitig for state "+arg1+" of server "+arg0+" failed.';"
+                         "if(!"+index+")throw new Error('Waitig for state "+arg1+" of server "+arg0+" failed.');"
                          "if(state=="+index+")return true;";
     if (timeout)
@@ -269,5 +271,5 @@
     TryCatch exception;
 
-    const Handle<Script> script = Script::Compile(String::New(code.c_str()));
+    const Handle<Script> script = Script::Compile(String::New(code.c_str()), String::New("internal"));
     if (script.IsEmpty())
         return Undefined();
@@ -874,5 +876,5 @@
     HandleScope handle_scope;
 
-    const Handle<Script> sleep = Script::Compile(String::New("dim.sleep();"));
+    const Handle<Script> sleep = Script::Compile(String::New("dim.sleep();"), String::New("internal"));
     if (sleep.IsEmpty())
         return Undefined();
@@ -1409,14 +1411,20 @@
         return false;
 
-    // Print (filename):(line number): (message).
-    const String::Utf8Value filename(message->GetScriptResourceName());
-
     ostringstream out;
 
-    if (*filename)
-        out << *filename << ": ";
-    out << "l." << message->GetLineNumber();
+    if (!message->GetScriptResourceName()->IsUndefined())
+    {
+        // Print (filename):(line number): (message).
+        const String::Utf8Value filename(message->GetScriptResourceName());
+
+        if (*filename)
+            out << *filename << ": ";
+        out << "l." << message->GetLineNumber();
+        if (*exception)
+            out << ": ";
+    }
+
     if (*exception)
-        out << ": " << *exception;
+        out << *exception;
 
     JsException(out.str());
@@ -1438,10 +1446,20 @@
     JsException(out.str());
 
-    String::Utf8Value stack_trace(try_catch->StackTrace());
+    const String::Utf8Value stack_trace(try_catch->StackTrace());
     if (stack_trace.length()<=0)
         return false;
 
-    //if (*stack_trace)
-    //    JsException(string("\n")+*stack_trace);
+    if (!*stack_trace)
+        return false;
+
+    const string trace(*stack_trace);
+
+    typedef boost::char_separator<char> separator;
+    const boost::tokenizer<separator> tokenizer(trace, separator("\n"));
+
+    auto it = tokenizer.begin();
+    JsException("");
+    while (it!=tokenizer.end())
+        JsException(*it++);
 
     return false;
@@ -1521,4 +1539,62 @@
 //                                  CORE
 // ==========================================================================
+
+void InterpreterV8::AddFormatToGlobal() const
+{
+    const string code =
+        "dim.format = function(str, arr)"
+        "{"
+            "var i = -1;"
+            "function callback(exp, p0, p1, p2, p3, p4/*, pos, str*/)"
+            "{"
+                "if (exp=='%%')"
+                    "return '%';"
+                ""
+                "if (arr[++i]===undefined)"
+                    "return undefined;"
+                ""
+                "var exp  = p2 ? parseInt(p2.substr(1)) : undefined;"
+                "var base = p3 ? parseInt(p3.substr(1)) : undefined;"
+                ""
+                "var val;"
+                "switch (p4)"
+                "{"
+                "case 's': val = arr[i]; break;"
+                "case 'c': val = arr[i][0]; break;"
+                "case 'f': val = parseFloat(arr[i]).toFixed(exp); break;"
+                "case 'p': val = parseFloat(arr[i]).toPrecision(exp); break;"
+                "case 'e': val = parseFloat(arr[i]).toExponential(exp); break;"
+                "case 'x': val = parseInt(arr[i]).toString(base?base:16); break;"
+                "case 'd': val = parseFloat(parseInt(arr[i], base?base:10).toPrecision(exp)).toFixed(0); break;"
+                "default:\n"
+                "    throw new SyntaxError('Conversion specifier '+p4+' unknown.');\n"
+                "}"
+                ""
+                "val = typeof(val)=='object' ? JSON.stringify(val) : val.toString(base);"
+                ""
+                "var sz = parseInt(p1); /* padding size */"
+                "var ch = p1 && p1[0]=='0' ? '0' : ' '; /* isnull? */"
+                "while (val.length<sz)"
+                    "val = p0 !== undefined ? val+ch : ch+val; /* isminus? */"
+                ""
+                "return val;"
+            "}"
+            ""
+            "var regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?(.)/g;"
+            "return str.replace(regex, callback);"
+        "}"
+        "\n"
+        "String.prototype.format = function()"
+        "{"
+            "return dim.format(this, Array.prototype.slice.call(arguments));"
+        "}"
+        "\n"
+        "var format = function()"
+        "{"
+            "return dim.format(arguments[0], Array.prototype.slice.call(arguments,1));"
+        "}";
+
+    Script::New(String::New(code.c_str()), String::New("internal"))->Run();
+}
 
 bool InterpreterV8::JsRun(const string &filename, const map<string, string> &map)
@@ -1587,4 +1663,6 @@
     fGlobalContext->Global()->Set(String::New("arg"), args, ReadOnly);
 
+    AddFormatToGlobal();
+
     JsStart(filename);
 
Index: trunk/FACT++/src/InterpreterV8.h
===================================================================
--- trunk/FACT++/src/InterpreterV8.h	(revision 14602)
+++ trunk/FACT++/src/InterpreterV8.h	(revision 14603)
@@ -171,4 +171,6 @@
     void JsHandleState(const std::string &, const State &);
 
+    void AddFormatToGlobal() const;
+
     bool JsRun(const std::string &, const std::map<std::string,std::string> & = std::map<std::string,std::string>());
     static void JsStop();
