From: handa Date: Mon, 8 Feb 2010 04:05:51 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: load_sync X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bf5b210a6d6d3939d49bdb17a20cb576990dbfe0;p=m17n%2Fm17n-lib-js.git *** empty log message *** --- diff --git a/index.html b/index.html index 794f865..b3f66f6 100644 --- a/index.html +++ b/index.html @@ -9,7 +9,7 @@ --> M17N Input Method by JavaScript - + @@ -22,9 +22,10 @@

debug Info

- - + + +
downpressstatuskeyseqrange
00
keykeycodestatuskeyseqrange
down0
press0

-
+
diff --git a/mim.js b/mim.js index 25d59e4..bb7f551 100644 --- a/mim.js +++ b/mim.js @@ -314,85 +314,65 @@ MIM.debug_print = function (event, ic) 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) @@ -401,7 +381,7 @@ 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; }; @@ -410,22 +390,17 @@ MIM.ic.prototype.reset = function () 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) @@ -453,7 +428,10 @@ MIM.handle_keyseq = function (event, ic) { 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"; @@ -487,20 +465,21 @@ MIM.reset_ic = function (event) 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); }; @@ -512,20 +491,23 @@ MIM.keypress = function (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; }; @@ -596,7 +578,7 @@ MIM.init = function () 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 () diff --git a/xex.js b/xex.js index 91135b2..9c49da3 100644 --- a/xex.js +++ b/xex.js @@ -1,40 +1,44 @@ // -* 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++) @@ -46,28 +50,34 @@ XEX.Subrountine.prototype.Call = function (domain, vari, args) 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; @@ -92,7 +102,7 @@ XEX.Lambda.prototype.Call = function (domain, vari, args) 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); @@ -108,24 +118,27 @@ XEX.Lambda.prototype.Call = function (domain, vari, args) 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); @@ -141,40 +154,573 @@ XEX.Macro.prototype.Call = function (domain, vari, args) 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 + ''; + 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 + ''; + } +} + +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 ''; + var str = ''; + for (i = 0; i < len; i++) + str += this.val[i].toString (); + return str + ''; } -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)); diff --git a/xex.xml b/xex.xml index bcadbbc..e5be038 100644 --- a/xex.xml +++ b/xex.xml @@ -1,5 +1,7 @@ - - - This is a test - + + 0 + 10 + 5 + +