if (! MIM.debug_nodes)
{
MIM.debug_nodes = new Array ();
- MIM.debug_nodes['status'] = document.getElementById ('status');
- MIM.debug_nodes['range'] = document.getElementById ('range');
MIM.debug_nodes['keydown'] = document.getElementById ('keydown');
MIM.debug_nodes['keypress'] = document.getElementById ('keypress');
- MIM.debug_nodes['keyseq'] = document.getElementById ('keyseq');
+ MIM.debug_nodes['status0'] = document.getElementById ('status0');
+ MIM.debug_nodes['status1'] = document.getElementById ('status1');
+ MIM.debug_nodes['keyseq0'] = document.getElementById ('keyseq0');
+ MIM.debug_nodes['keyseq1'] = document.getElementById ('keyseq1');
+ MIM.debug_nodes['range0'] = document.getElementById ('range0');
+ MIM.debug_nodes['range1'] = document.getElementById ('range1');
}
var target = event.target;
var code = event.keyCode;
var ch = event.type == 'keydown' ? 0 : event.charCode;
var key = MIM.decode_key (event);
var keyseq = "";
+ var index;
MIM.debug_nodes[event.type].innerHTML = "" + code + "/" + ch + " : " + key;
- MIM.debug_nodes['status'].innerHTML = ic.im.status;
+ index = (event.type == 'keydown' ? '0' : '1');
+ MIM.debug_nodes['status' + index].innerHTML = ic.im.status;
for (var i = 0; i < ic.keyseq.length; i++)
keyseq += ic.keyseq[i];
- MIM.debug_nodes['keyseq'].innerHTML = keyseq + ":" + ic.keyseq.length;
- MIM.debug_nodes['range'].innerHTML = "" + ic.range[0] + "," + ic.range[1];;
+ MIM.debug_nodes['keyseq' + index].innerHTML
+ = keyseq + ":" + ic.keyseq.length;
+ MIM.debug_nodes['range' + index].innerHTML
+ = "" + ic.range[0] + ":" + ic.range[1];
};
MIM.get_range = function (target, range)
{
- if (target.selectionStart != null)
+ if (target.selectionStart != null) // for Mozilla
{
- // for Mozilla
range[0] = target.selectionStart;
range[1] = target.selectionEnd;
- return true;
}
- if (document.selection != null)
+ else // for IE
{
- target.focus();
-
- var range = document.selection.createRange ();
- var bookmark = range.getBookmark ();
- var value = target.value;
- var saved_value = value;
- var marker = "_#_MARKER_#_";
- while (value.indexOf (marker) != -1)
- marker += "#_";
- var parent = range.parentElement ();
- if (parent == null || parent.type != "textarea")
- {
- range[0] = range[1] = 0;
- }
- else
- {
- range.text = marker + range.text + marker;
- contents = this.element.value;
- range[0] = contents.indexOf (marker);
- contents = contents.replace(marker, "");
- range[1] = contents.indexOf(marker);
- target.value = originalContents;
- range.moveToBookmark (bookmark);
- range.select ();
- }
- return true;
+ var r = document.selection.createRange ();
+ var rr = r.duplicate ();
+
+ rr.moveToElementText (target);
+ rr.setEndPoint ('EndToEnd', range);
+ range[0] = rr.text.length - r.text.length;
+ range[1] = rr.text.length;
}
- return false;
-};
+}
MIM.set_caret = function (target, pos)
{
- if(/*@cc_on ! @*/ false) // IE
- {
- var range = target.createTextRange ();
- range.move ('character', pos);
- ranges.elect ();
- return true;
- }
if (target.selectionStart != null) // Mozilla
{
target.focus ();
target.setSelectionRange (pos, pos);
- return true;
}
- // Unknown
- target.focus ();
- return false;
+ else // IE
+ {
+ var range = target.createTextRange ();
+ range.move ('character', pos);
+ range.select ();
+ }
};
MIM.ic = function (im, target)
this.target = target;
this.key = false;
this.keyseq = new Array ();
- this.range = new Array (-1, -1);
+ this.range = new Array (0, 0);
return this;
};
this.key = false;
while (this.keyseq.length > 0)
this.keyseq.pop ();
- this.range[0] = this.range[1] = -1;
};
-MIM.ic.prototype.check_caret = function ()
+MIM.ic.prototype.check_range = function ()
{
- var from = this.range[0];
- var to = this.range[1];
+ var from = this.range[0], to = this.range[1];
MIM.get_range (this.target, this.range);
- if (from >= 0)
- {
- if (this.range[0] != this.range[1] || to != this.range[0])
- this.reset ();
- else
- this.range[0] = from;
- }
+ if (this.range[0] != this.range[1] || to != this.range[1])
+ this.reset ();
+ else
+ this.range[0] = from;
};
MIM.insert = function (ic, insert)
{
MIM.insert (ic, map['_target_text']);
if (! ('_has_child' in map))
- ic.reset ();
+ {
+ ic.reset ();
+ ic.range[0] = ic.range[1];
+ }
event.preventDefault ();
//document.getElementById ('text').value
//= keyseq_string (ic.keyseq) + " handled";
MIM.keydown = function (event)
{
- if (! (event.target.type == "text" || event.target.type == "textarea"))
+ var target = event.target;
+ if (! (target.type == "text" || target.type == "textarea"))
return;
- var ic = event.target.mim_ic;
+ var ic = target.mim_ic;
if (! ic || ic.im != MIM.current_im)
{
- ic = new MIM.ic (MIM.current_im, event.target);
- event.target.mim_ic = ic;
+ ic = new MIM.ic (MIM.current_im, target);
+ target.mim_ic = ic;
+ MIM.add_event_listener (target, 'blur', MIM.reset_ic);
}
- MIM.add_event_listener (event.target, 'blur', MIM.reset_ic);
- MIM.debug_print (event, ic);
if (ic.im.status < 0)
return;
- ic.check_caret ();
+ ic.check_range ();
+ MIM.debug_print (event, ic);
ic.key = MIM.decode_key (event);
};
var ic = event.target.mim_ic;
var i;
- MIM.debug_print (event, ic);
- if (ic.im.status < 0)
- return;
- if (! ic.key)
- ic.key = MIM.decode_key (event);
- if (! ic.key)
- {
- ic.reset ();
+ try {
+ if (ic.im.status < 0)
return;
- }
- ic.keyseq.push (ic.key);
- if (ic.im.status == 1) // Still loading.
- return;
- MIM.handle_keyseq (event, ic);
+ if (! ic.key)
+ ic.key = MIM.decode_key (event);
+ if (! ic.key)
+ {
+ ic.reset ();
+ return;
+ }
+ ic.keyseq.push (ic.key);
+ if (ic.im.status == 1) // Still loading.
+ return;
+ MIM.handle_keyseq (event, ic);
+ } finally {
+ MIM.debug_print (event, ic);
+ }
return;
};
MIM.server = 'http://localhost/mim';
MIM.current_im = MIM.register ('latin', 'post', 'latn-post.js');
MIM.register ('th', 'kesmanee', 'th-kesmanee.js');
- MIM.load_sync (MIM.current_im);
+ MIM.load (MIM.current_im);
};
MIM.init_debug = function ()
// -* coding: utf-8; -*
-var XEX = {};
+var Xex = {};
-XEX.Variable = function (domain, name, val)
+Xex.Variable = function (domain, name, val)
{
this.domain = domain;
this.name = name;
this.val = val;
}
-XEX.Variable.prototype = {
- value: function () { return this.val; },
- set_value: function (val) {
- this.val = val;
- return val;
- },
- clone: function () {
- {
- return new XEX.Variable (this.domain, this.name, this.value);
- }
- }
+Xex.Variable.prototype.clone = function () {
+ return new Xex.Variable (this.domain, this.name, this.value);
}
-XEX.Function = function (name, with_var, min_args, max_args) {
+Xex.Variable.prototype.Equals = function (obj) {
+ return ((obj instanceof Xex.Variable)
+ && obj.name == this.name);
+}
+
+Xex.Variable.prototype.SetValue = function (term) {
+ this.val = term;
+ return term;
+}
+
+Xex.Function = function (name, with_var, min_args, max_args) {
this.name = name;
this.with_var = with_var;
this.min_args = min_args;
this.max_args = max_args;
};
-XEX.Subrountine = function (builtin, name, with_var, min_args, max_args) {
- this.prototype = new XEX.Function (name, with_var, min_args, max_args);
+Xex.Subrountine = function (builtin, name, with_var, min_args, max_args) {
+ this.name = name;
+ this.with_var = with_var;
+ this.min_args = min_args;
+ this.max_args = max_args;
this.builtin = builtin;
-};
+}
-XEX.Subrountine.prototype.Call = function (domain, vari, args)
+Xex.Subrountine.prototype.Call = function (domain, vari, args)
{
newargs = new Array ();
for (var i = 0; i < args.length; i++)
return this.builtin (domain, vari, newargs)
}
-XEX.SpecialForm = function (builtin, name, with_var, min_args, max_args)
+Xex.SpecialForm = function (builtin, name, with_var, min_args, max_args)
{
- this.prototype = new XEX.Function (name, with_var, min_args, max_args);
+ this.name = name;
+ this.with_var = with_var;
+ this.min_args = min_args;
+ this.max_args = max_args;
this.builtin = builtin;
}
-XEX.SpecialForm.prototype.Call = function (domain, vari, args)
+Xex.SpecialForm.prototype.Call = function (domain, vari, args)
{
return this.builtin (domain, vari, args)
}
-XEX.Lambda = function (name, min_args, max_args, args, body)
+Xex.Lambda = function (name, min_args, max_args, args, body)
{
- this.prototype = new XEX.Function (name, false, min_args, max_args);
+ this.name = name;
+ this.with_var = with_var;
+ this.min_args = min_args;
+ this.max_args = max_args;
this.args = args;
this.body = body;
}
-XEX.Lambda.prototype.Call = function (domain, vari, args)
+Xex.Lambda.prototype.Call = function (domain, vari, args)
{
var current = domain.bindings;
- var result = XEX.Term.zero;
+ var result = Xex.Zero;
var limit = max_args >= 0 ? args.length : args.length - 1;
var i;
domain.Bind (this.args[limit], list);
}
try {
- domain.Catch (XEX.CatchTag.Return);
+ domain.Catch (Xex.CatchTag.Return);
for (var term in this.body)
{
result = term.Eval (domain);
return result;
}
-XEX.Macro = function (name, min_args, max_args, args, body)
+Xex.Macro = function (name, min_args, max_args, args, body)
{
- this.prototype = new XEX.Function (name, false, min_args, max_args);
+ this.name = name;
+ this.with_var = with_var;
+ this.min_args = min_args;
+ this.max_args = max_args;
this.args = args;
this.body = body;
}
-XEX.Macro.prototype.Call = function (domain, vari, args)
+Xex.Macro.prototype.Call = function (domain, vari, args)
{
var current = domain.bindings;
- var result = XEX.Term.Zero;
+ var result = Xex.Zero;
var i;
try {
for (i = 0; i < args.length; i++)
domain.Bind (this.args[i], args[i]);
try {
- domain.Catch (XEX.CatchTag.Return);
+ domain.Catch (Xex.CatchTag.Return);
for (var term in body)
{
result = term.Eval (domain);
return result;
}
-XEX.EvalConstant = function (domain)
+Xex.Bindings = function (vari)
{
- if (this.nodeName == 'integer')
- alert ("integer:" + this.attributes[0].nodeValue);
- else if (this.nodeName == 'string')
- alert ("string:" + this.firstChild.nodeValue);
- return this;
+ this.vari = vari;
+ this.old_value = vari.val;
+}
+
+Xex.Bindings.prototype.UnboundTo = function (boundary)
+{
+ for (var b = this; b != boundary; b = b.next)
+ b.vari.val = b.old_value;
+ return boundary;
+}
+
+Xex.Bind = function (bindings, vari, val)
+{
+ var b = new Xex.Bindings (vari);
+ b.vari.val = val;
+ b.next = bindings;
+ return b;
+}
+
+Xex.CatchTag = {
+ Return: 0,
+ Break: 1
+}
+
+Xex.Domain = function (name, parent, context)
+{
+ this.name = name;
+ this.context = context;
+ this.depth = 0;
+ this.termtypes = parent ? parent.termtypes.slice () : new Array ();
+ this.functions = parent ? parent.functions.slice () : new Array ();
+ this.variables = parent ? parent.variable.slice () : new Array ();
+
+ var call_stack = new Array ();
+ var bindings;
+ var catch_stack = new Array ();
+ var catch_count = 0;
+
+ if (this.CallStackCount)
+ return;
+
+ var proto = Xex.Domain.prototype;
+
+ proto.CallStackCount = function () { return call_stack.length; }
+ proto.CallStackPush = function (term) { call_stack.push (term); }
+ proto.CallStackPop = function () { call_stack.pop (); }
+ proto.Bind = function (vari, val)
+ {
+ bindings = Xex.Bind (bindings, vari, val);
+ }
+ proto.UnboundTo = function (boundary)
+ {
+ if (bindings)
+ bindings = bindings.UnboundTo (boundary);
+ }
+ proto.Catch = function (tag) { catch_stack.push (tag); catch_count++; }
+ proto.Uncatch = function ()
+ {
+ catch_stack.pop ();
+ if (catch_count > catch_stack.length)
+ catch_count--;
+ }
+ proto.Thrown = function ()
+ {
+ var i = catch_stack.length - catch_count;
+ return (i > 0 ? i - 1 : false);
+ }
+ proto.ThrowReturn = function ()
+ {
+ for (var i = catch_stack.length - 1; i >= 0; i--)
+ {
+ catch_count--;
+ if (catch_stack[i] == Xex.CatchTag.Return)
+ break;
+ }
+ }
+ proto.ThrowBreak = function ()
+ {
+ if (catch_stack[catch_stack.length - 1] != Xex.CatchTag.Break)
+ throw new Xex.Error (Xex.Error.NoLoopToBreak,
+ "No surrounding loop to break");
+ catch_count--;
+ }
+ proto.ThrowSymbol = function (tag)
+ {
+ var i = catch_count;
+ for (var j = catch_stack.length - 1; j >= 0; j--)
+ {
+ i--;
+ if (Xex.CatchTag.Matches (catch_stack[i], tag))
+ {
+ catch_count = i;
+ return;
+ }
+ }
+ throw new Xex.Error (Xex.Error.UncaughtThrow,
+ "No corresponding catch: " + tag);
+ }
+ proto.DefType = function (obj)
+ {
+ var type = obj.type;
+ if (this.termtypes[type])
+ throw new Xex.Error (Xex.Error.TermTypeInvalid,
+ "Already defined: " + type);
+ if (this.functions[type])
+ throw new Xex.Error (Xex.Error.TermTypeInvalid,
+ "Already defined as a funciton or a macro: "
+ + type);
+ this.termtypes[type] = obj.Parser;
+ }
+
+ proto.DefSubr = function (builtin, name, with_var, min_args, max_args)
+ {
+ this.functions[name] = new Xex.Subrountine (builtin, name, with_var,
+ min_args, max_args);
+ }
+ proto.DefSpecial = function (builtin, name, with_var, min_args, max_args)
+ {
+ this.functions[name] = new Xex.SpecialForm (builtin, name, with_var,
+ min_args, max_args);
+ }
+ proto.Defun = function (name, min_args, max_args, args, body)
+ {
+ this.functions[name] = new Xex.Lambda (name, min_args, max_args,
+ args, body);
+ }
+ proto.DefunByFunc = function (func) { this.functions[func.Name] = func; }
+ proto.Defmacro = function (name, min_args, max_args, args, body)
+ {
+ this.functions[name] = new Xex.Macro (name, min_args, max_args, args, body);
+ }
+ proto.DefAlias = function (alias, fname)
+ {
+ var func = this.functions[fname];
+
+ if (this.termtypes[alias])
+ throw new Xex.Error (Xex.Error.FunctionConflict,
+ "Already defined as a term type: " + alias);
+ if (this.functions[alias])
+ throw new Xex.Error (Xex.Error.FunctionConflict,
+ "Already defined as a function: " + alias);
+ if (! func)
+ throw new Xex.Error (Xex.Error.UnknownFunction, fname);
+ this.functions[alias] = func;
+ }
+ proto.Defvar = function (name)
+ {
+ var vari = this.variables[name];
+ if (vari)
+ {
+ if (vari.Typed)
+ throw new Xex.Error (Xex.Error.VariableTypeConflict,
+ "Not a non-typed variable: " + name);
+ }
+ else
+ {
+ vari = new Xex.Variable (this, name, Xex.Zero);
+ this.variables[name] = vari;
+ }
+ return vari;
+ }
+ proto.GetFunc = function (name) { return this.functions[name]; }
+ proto.CopyFunc = function (domain, name)
+ {
+ var func = this.functions[name];
+ domain.DefunByFunc (func);
+ return true;
+ }
+ proto.CopyFuncAll = function (domain)
+ {
+ for (var i = this.functions.length - 1; i >= 0; i--)
+ domain.DefunByFunc (this.functions[i]);
+ }
+ proto.GetVarCreate = function (name)
+ {
+ var vari = this.variables[name];
+ if (! vari)
+ this.variables[name] = vari
+ = new Xex.Variable (this, name, Xex.Zero);
+ return vari;
+ }
+ proto.GetVar = function (name) { return this.variables[name]; }
+ proto.SaveValues = function ()
+ {
+ values = new Array ()
+ for (var i = this.variables.length - 1; i >= 0; i--)
+ {
+ var vari = this.variables[i];
+ values[vari.Name] = vari.val.Clone ();
+ }
+ return values;
+ }
+ proto.RestoreValues = function (values)
+ {
+ var name;
+ for (name in values)
+ {
+ var vari = this.variables[name];
+ vari.val = values[name];
+ }
+ }
};
-XEX.EvalFuncall = function (domain)
+Xex.Term = function () { }
+Xex.Term.prototype = {
+ IsTrue: true,
+ Eval: function (domain) { return this.Clone (); },
+ Equals: function (obj)
+ {
+ return (this.type == obj.type
+ && this.val
+ && obj.val == this.val);
+ },
+ Matches: function (obj) { return this.Equals (obj); },
+ toString: function ()
+ {
+ if (this.val != undefined)
+ return '<' + this.type + '>' + this.val + '</' + this.type + '>';
+ return '<' + this.type + '/>';
+ }
+};
+
+Xex.ParseTerm = function (domain, node)
{
- try {
- domain.CallStackPush (this);
- } catch (e) {
- alert (e);
+ var name = node.nodeName;
+ var parser = domain.termtypes[name];
+
+ if (parser)
+ return parser (domain, node);
+ if (name == 'defun' || name == 'defmacro')
+ {
+ name = parse_defun_head (domain, node);
+ parse_defun_body (domain, node);
+ return new Xex.StrTerm (name);
+ }
+ if (name == 'defvar')
+ {
+ name = parse_defvar (doamin, node);
+ return new Xex.StrTerm (nanme);
+ }
+
+ return new Xex.Funcall.prototype.Parser (domain, node);
+}
+
+Xex.Varref = function (vname)
+{
+ var vari;
+
+ this.val = vname;
+ if (this.type)
+ return;
+ var proto = Xex.Varref.prototype;
+
+ proto.type = 'varref';
+
+ proto.Clone = function () { return new Xex.Varref (this.val); }
+ proto.Eval = function (domain)
+ {
+ if (! vari || vari.domain != domain)
+ vari = domain.GetVarCreate (this.val);
+ return vari.val;
+ }
+
+ proto.Parser = function (domain, node)
+ {
+ return new Xex.Varref (node.attributes['vname'].nodeValue);
}
}
-var obj = new XMLHttpRequest ();
-obj.open ('GET', 'xex.xml', false);
-obj.send ('');
-var body = obj.responseXML.firstChild;
-for (var i = body.childNodes.length - 1; i >= 0 ; i--)
+Xex.Varref.prototype = new Xex.Term ();
+
+var null_args = new Array ();
+
+Xex.Funcall = function (func, vari, args)
+{
+ this.func = func;
+ if (! args)
+ args = null_args;
+ this.vari = vari;
+ this.args = args;
+ if (this.type)
+ return;
+
+ var proto = Xex.Funcall.prototype;
+
+ proto.type = 'funcall';
+
+ proto.Parser = function (domain, node)
{
- var node = body.childNodes[i];
- if (node.nodeType == 1)
- node.Eval = XEX.EvalConstant;
- else
- body.removeChild (node);
+ var fname = node.nodeName;
+ var attr;
+
+ if (fname == 'funcall')
+ fname = node.attributes['fname']
+ var func = domain.GetFunc (fname);
+ var vari;
+ attr = node.attributes['vname'];
+ vari = attr != undefined ? domain.GetVarCreate (attr.nodeValue) : false;
+ var args = new Array ();
+ for (node = node.firstChild; node; node = node.nextSibling)
+ if (node.nodeType == 1)
+ args.push (Xex.ParseTerm (domain, node));
+ return new Xex.Funcall (func, vari, args);
+ }
+
+ proto.Eval = function (domain)
+ {
+ return this.func.Call (domain, this.vari, this.args);
+ }
+
+ proto.Clone = function ()
+ {
+ return new Xex.Funcall (this.func, this.vari, this.args);
+ }
+
+ proto.Equals = function (obj)
+ {
+ return (obj.type == 'funcall'
+ && obj.func == this.func
+ && obj.vari.Equals (this.vari)
+ && obj.args.length == this.func.length);
+ }
+
+ proto.toString = function ()
+ {
+ var arglist = ''
+ var len = this.args.length;
+ if (len == 0)
+ return '<' + this.func.name + '/>';
+ for (var i = 0; i < len; i++)
+ arglist += this.args[i].toString ();
+ return '<' + this.func.name + '>' + arglist + '</' + this.func.name + '>';
+ }
+}
+
+Xex.Funcall.prototype = new Xex.Term ();
+
+Xex.ErrTerm = function (ename, message, stack)
+{
+ if (this.type)
+ return;
+
+ var proto = Xex.ErrTerm.prototype;
+
+ proto.type = 'error';
+
+ proto.Parser = function (domain, node)
+ {
+ return new Xex.ErrTerm (node.attributes['ename'].nodeValue,
+ node.innerText, false);
+ }
+
+ proto.CallStack = function () { return stack; }
+
+ proto.SetCallStack = function (value) { statck = value; }
+
+ proto.Clone = function ()
+ {
+ return new Xex.ErrTerm (ename, message, false);
+ }
+
+ proto.Equals = function (obj)
+ {
+ return (obj.type == 'error'
+ && obj.ename == ename && obj.message == message
+ && (obj.stack ? (stack && stack.length == obj.stack.length)
+ : ! stack));
+ }
+
+ proto.Matches = function (obj)
+ {
+ return (obj.type == 'error' && obj.ename == ename);
+ }
+}
+
+Xex.ErrTerm.prototype = new Xex.Term ();
+
+Xex.IntTerm = function (num)
+{
+ this.val = num;
+ this.IsTrue = num != 0;
+ if (this.type)
+ return;
+ var proto = Xex.IntTerm.prototype;
+ proto.type = 'integer';
+ proto.Clone = function () { return new Xex.IntTerm (this.val); }
+ proto.Parser = function (domain, node)
+ {
+ return new Xex.IntTerm (parseInt (node.firstChild.nodeValue));
+ }
+}
+
+Xex.IntTerm.prototype = new Xex.Term ();
+
+Xex.StrTerm = function (str)
+{
+ this.val = str;
+ this.IsTrue = str && str.length > 0;
+ if (this.type)
+ return;
+ var proto = Xex.StrTerm.prototype;
+ proto.type = 'string';
+ proto.Clone = function () { return new Xex.StrTerm (this.val); }
+ proto.Parser = function (domain, node)
+ {
+ return new Xex.StrTerm (node.firstChild.nodeValue);
+ }
+}
+
+Xex.StrTerm.prototype = new Xex.Term ();
+
+Xex.LstTerm = function (list)
+{
+ this.val = list;
+ this.IsTrue = list && list.length > 0;
+ if (this.type)
+ return;
+
+ var proto = Xex.LstTerm.prototype;
+
+ proto.type = 'list';
+
+ proto.Clone = function () { return new Xex.LstTerm (this.val.slice ()); }
+
+ proto.Equals = function (obj)
+ {
+ if (obj.type != 'list' || obj.val.length != this.val.length)
+ return false;
+ var i, len = this.val.length;
+ for (i = 0; i < len; i++)
+ if (! this.val[i].Equals (obj.val[i]))
+ return false;
+ return true;
+ }
+
+ proto.Parser = function (domain, node)
+ {
+ var list = new Array ();
+
+ for (node = node.firstChild; node; node = node.nextSibling)
+ if (node.nodeType == 1)
+ list.push (Xex.ParseTerm (domain, node));
+ return new Xex.LstTerm (list);
+ }
+
+ proto.toString = function ()
+ {
+ var len = this.val.length;
+
+ if (len == 0)
+ return '<list/>';
+ var str = '<list>';
+ for (i = 0; i < len; i++)
+ str += this.val[i].toString ();
+ return str + '</list>';
}
-for (var i = 0; i < body.childNodes.length; i++)
+}
+
+Xex.LstTerm.prototype = new Xex.Term ();
+
+(function () {
+ var basic = new Xex.Domain ('basic');
+
+ function Fset (domain, vari, args)
{
- var node = body.childNodes[i];
- node.Eval ();
+ return vari.SetValue (args[0]);
}
+ function maybe_set_intvar (vari, n)
+ {
+ var term = new Xex.IntTerm (n);
+ if (vari != null)
+ vari.SetValue (term);
+ return term;
+ }
+ function Fadd (domain, vari, args)
+ {
+ var n = vari ? vari.val.val : 0;
+ var len = args.length;
+
+ for (var i = 0; i < len; i++)
+ n += args[i].val;
+ return maybe_set_intvar (vari, n);
+ }
+
+ function Fand (domain, vari, args)
+ {
+ var len = args.length;
+ for (var i = 0; i < len; i++)
+ {
+ var result = args[i].Eval (domain);
+ if (domain.Thrown ())
+ return result;
+ if (! result.IsTrue)
+ return Xex.Zero;
+ }
+ return Xex.One;
+ }
+
+ function For (domain, vari, args)
+ {
+ var len = args.length;
+ for (var i = 0; i < len; i++)
+ {
+ var result = args[i].Eval (domain);
+ if (domain.Thrown ())
+ return result;
+ if (result.IsTrue)
+ return Xex.One;
+ }
+ return Xex.Zero;
+ }
+
+ function Fprogn (domain, vari, args)
+ {
+ var result = Xex.One;
+ var len = args.length;
+
+ for (var i = 0; i < len; i++)
+ {
+ result = args[i].Eval (domain);
+ if (domain.Thrown ())
+ return result;
+ }
+ return result;
+ }
+
+ function Fif (domain, vari, args)
+ {
+ var result = args[0].Eval (domain);
+
+ if (domain.Thrown ())
+ return result;
+ if (result.IsTrue)
+ return args[1].Eval (domain);
+ if (args.Length == 2)
+ return Zero;
+ return args[2].Eval (domain);
+ }
+
+ basic.DefSubr (Fset, "set", true, 1, 1);
+ basic.DefSubr (Fadd, "add", true, 1, -1);
+ basic.DefSpecial (Fand, "and", false, 1, -1);
+ basic.DefSpecial (For, "or", false, 1, -1);
+ basic.DefAlias ("=", "set");
+ basic.DefSpecial (Fprogn, "progn", false, 1, -1);
+ basic.DefSpecial (Fif, "if", false, 2, 3);
+ basic.DefType (new Xex.Funcall ());
+ basic.DefType (new Xex.Varref ());
+ basic.DefType (new Xex.ErrTerm ());
+ basic.DefType (new Xex.IntTerm ());
+ basic.DefType (new Xex.StrTerm ());
+ basic.DefType (new Xex.LstTerm ());
+
+ Xex.Domain.basic = basic;
+}) ();
+
+Xex.Zero = new Xex.IntTerm (0);
+Xex.One = new Xex.IntTerm (1);
+
+var obj = new XMLHttpRequest ();
+obj.open ('GET', 'xex.xml', false);
+obj.send ('');
+var body = obj.responseXML.firstChild;
+var domain = Xex.Domain.basic;
+document.ATTR = body;
+alert (Xex.ParseTerm (domain, body).Eval (domain));