UnknownFunction: "unknown-function",
MacroExpansionError: "macro-expansion-error",
- NoVariableName: "no-variable-anme",
+ NoVariableName: "no-variable-name",
+ NoFunctionName: "no-funcion-name",
// Run time errors.
ArithmeticError: "arithmetic-error",
UncaughtThrow: "uncaught-throw"
};
-Xex.Variable = function (domain, name, val)
+Xex.Variable = function (domain, name, desc, val, range)
{
this.domain = domain;
this.name = name;
+ this.desc = desc;
this.val = val;
+ this.range = range;
}
Xex.Variable.prototype.clone = function () {
- return new Xex.Variable (this.domain, this.name, this.value);
+ return new Xex.Variable (this.domain, this.name, this.desc,
+ this.val, this.range);
}
Xex.Variable.prototype.Equals = function (obj) {
throw new Xex.ErrTerm (Xex.Error.UnknownFunction, fname);
this.functions[alias] = func;
},
- Defvar: function (name)
+ Defvar: function (name, desc, val, range)
{
- if (name instanceof Xex.Variable)
- {
- name = name.Clone (this);
- this.variables[name.name] = name;
- return name;
- }
- var vari = this.variables[name];
- if (vari)
- {
- if (vari.Typed)
- throw new Xex.ErrTerm (Xex.Error.VariableTypeConflict,
- "Not a non-typed variable: " + name);
- }
- else
- {
- vari = new Xex.Variable (this, name, Xex.Zero);
- this.variables[name] = vari;
- }
+ var vari = new Xex.Variable (name, desc, val, range);
+ this.variables[name] = vari;
return vari;
},
GetFunc: function (name)
{
var vari = this.variables[name];
if (! vari)
- vari = this.variables[name] = new Xex.Variable (this, name, Xex.Zero);
+ vari = this.variables[name] = new Xex.Variable (this, name, null,
+ Xex.Zero, null);
return vari;
},
GetVar: function (name) { return this.variables[name]; },
}
};
-Xex.ParseTerm = function (domain, node)
+Node.prototype.firstElement = function ()
{
- 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);
+ for (var n = this.firstChild; n; n = n.nextSibling)
+ if (n.nodeType == 1)
+ return n;
+ return null;
}
-Xex.ParseTermList = function (domain, node)
+Node.prototype.nextElement = function ()
{
- for (var n = node; n; n = n.nextSibling)
+ for (var n = this.nextSibling; n; n = n.nextSibling)
if (n.nodeType == 1)
+ return n;
+ return null;
+};
+
+(function () {
+ function parse_defvar (domain, node)
+ {
+ var name = node.attributes['vname'].nodeValue;
+ if (! name)
+ throw new Xex.ErrTerm (Xex.Error.NoVariableName, node, '');
+ var vari = domain.variables['name'];
+ var desc, val, range;
+ if (vari)
+ {
+ desc = vari.description;
+ val = vari.val;
+ range = vari.range;
+ }
+ node = node.firstElement ();
+ if (node && node.nodeName == 'description')
+ {
+ desc = node.firstChild.nodeValue;
+ node = node.nextElement ();
+ }
+ if (node)
+ {
+ val = Xex.Term.Parse (domain, node);
+ node = node.nextElement ();
+ if (node && node.nodeName == 'possible-values')
+ for (node = node.firstElement (); node; node = node.nextElement ())
+ {
+ var pval;
+ if (node.nodeName == 'range')
+ {
+ if (! val.IsInt)
+ throw new Xex.ErrTerm (Xex.Error.TermTypeInvalid,
+ 'Range not allowed for ' + name);
+ pval = new Array ();
+ for (var n = node.firstElement (); n; n = n.nextElement ())
+ {
+ var v = Xex.Term.Parse (domain, n);
+ if (! v.IsInt)
+ throw new Xex.ErrTerm (Xex.Error.TermTypeInvalid,
+ 'Invalid range value: ' + val);
+ pval.push (v);
+ }
+ }
+ else
+ {
+ pval = Xex.Term.Parse (domain, node);
+ if (val.type != pval.type)
+ throw new Xex.ErrTerm (Xex.Error.TermTypeInvalid,
+ 'Invalid possible value: ' + pval);
+ }
+ if (! range)
+ range = new Array ();
+ range.push (pval);
+ }
+ }
+ if (! val)
+ val = Xex.Zero;
+ domain.Defvar (name, desc, val, range);
+ return name;
+ }
+
+ function parse_defun_head (domain, node)
+ {
+ var name = node.attributes['fname'].nodeValue;
+ if (! name)
+ throw new Xex.ErrTerm (Xex.Error.NoFunctionName, node, '');
+ var args = new Array ();
+ var nfixed = 0, noptional = 0, nrest = 0;
+
+ node = ndoe.firstElement ();
+ if (node && node.nodeName == 'args')
+ {
+ var n;
+ for (n = n.firstElement (); n; n = n.nextElement ())
+ {
+ if (n.nodeName == 'fixed')
+ nfixed++;
+ else if (n.nodeName == 'optional')
+ noptional++;
+ else if (n.nodeName == 'rest')
+ nrest++;
+ else
+ throw new Xex.ErrTerm (Xex.Error.WrongType, n, n.nodeName);
+ }
+ if (nrest > 1)
+ throw new Xex.ErrTerm (Xex.Error.WrongType, n, 'Too many <rest>');
+ for (n = node.firstElement (); n; n = n.nextElement ())
+ args.push (domain.DefVar (n.attributes['vname'].nodeValue));
+ }
+ args.min_args = nfixed;
+ args.max_args = nrest == 0 ? nfixed + noptional : -1;
+
+ if (node.nodeName == 'defun')
+ domain.Defun (name, args, null);
+ else
+ domain.Defmacor (name, args, null);
+ return name;
+ }
+
+ function parse_defun_body (domain, node)
+ {
+ var name = node.attributes['fname'].nodeValue;
+ var func = domain.GetFunc (name);
+ var body;
+ for (node = node.firstElement (); node; node = node.nextElement ())
+ if (node.nodeName != 'description' && node.nodeName != 'args')
+ break;
+ body = Xex.Term.Parse (domain, node, null);
+ func.SetBody (body);
+ }
+
+ Xex.Term.Parse = function (domain, node, stop)
+ {
+ if (arguments.length == 2)
+ {
+ 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 (domain, node);
+ return new Xex.StrTerm (name);
+ }
+ return new Xex.Funcall.prototype.Parser (domain, node);
+ }
+ for (var n = node; n && n != stop; n = n.nextElement ())
{
if (n.nodeName == 'defun' || n.nodeName == 'defmacro')
Xex.parse_defun_head (domain, n);
}
- var terms = false;
- for (var n = node; n; n = n.nextSibling)
- if (n.nodeType == 1)
+ var terms = null;
+ for (var n = node; n && n != stop; n = n.nextElement ())
{
- if (! terms)
- terms = new Array ();
if (n.nodeName == 'defun' || n.nodeName == 'defmacro')
Xex.parse_defun_body (domain, n);
else if (n.nodeName == 'defvar')
- Xex.parse_defvar (domain, n);
+ parse_defvar (domain, n);
else
- terms.push (Xex.ParseTerm (domain, n));
+ {
+ if (! terms)
+ terms = new Array ();
+ terms.push (Xex.Term.Parse (domain, n));
+ }
}
- return terms;
-}
+ return terms;
+ }
+}) ();
Xex.Varref = function (vname)
{
var vari;
attr = node.attributes['vname'];
vari = attr != undefined ? domain.GetVarCreate (attr.nodeValue) : false;
- var args = Xex.ParseTermList (domain, node.firstChild);
+ var args = Xex.Term.Parse (domain, node.firstElement (), null);
return new Xex.Funcall (func, vari, args);
}
proto.Parser = function (domain, node)
{
- var list = Xex.ParseTermList (domain, node.firstChild);
+ var list = Xex.Term.Parse (domain, node.firstElement (), null);
return new Xex.LstTerm (list);
}
enabled: true,
// Boolean flag to tell if MIM is running in debug mode or not.
debug: false,
- // List of registered input methods.
- im_list: {},
+ // List of main input methods.
+ imlist: {},
+ // List of extra input methods;
+ imextra: {},
// Global input method data
im_global: null,
// Currently selected input method.
for (node = node.firstChild; node; node = node.nextSibling)
if (node.nodeType == 1)
{
- var term = Xex.ParseTerm (domain, node);
+ var term = Xex.Term.Parse (domain, node);
return new MIM.KeySeq (term);
}
throw new Xex.ErrTerm (MIM.Error.ParseError, "Invalid keyseq");
this.val = name;
}
MIM.Selector.prototype = new Xex.Term ('selector');
+
(function () {
var selectors = {};
selectors["@<"] = selectors["@first"] = new MIM.Selector ('@<');
for (n = node.firstChild; n && n.nodeType != 1; n = n.nextSibling);
if (! n)
throw new Xex.ErrTerm (MIM.Error.ParseError, "invalid rule:" + node);
- var keyseq = Xex.ParseTerm (domain, n);
+ var keyseq = Xex.Term.Parse (domain, n);
if (keyseq.type != 'keyseq')
throw new Xex.ErrTerm (MIM.Error.ParseError, "invalid rule:" + node);
- var actions = Xex.ParseTermList (domain, n.nextSibling);
+ var actions = Xex.Term.Parse (domain, n.nextElement (), null);
return new MIM.Rule (keyseq, actions);
}
MIM.Rule.prototype.toString = function ()
this.name = name;
this.rules = new Array ();
};
+
(function () {
var proto = new Xex.Term ('map');
var map = new MIM.Map (name);
for (var n = node.firstChild; n; n = n.nextSibling)
if (n.nodeType == 1)
- map.rules.push (Xex.ParseTerm (domain, n));
+ map.rules.push (Xex.Term.Parse (domain, n));
return map;
}
this.submaps = null;
this.actions = null;
};
+
(function () {
var proto = {};
this.name = name;
this.keymap = new MIM.Keymap ();
};
+
(function () {
var proto = new Xex.Term ('state');
if (! name)
throw new Xex.ErrTerm (MIM.Error.ParseError, "invalid map");
var state = new MIM.State (name);
- for (node = node.firstChild; node; node = node.nextSibling)
+ for (node = node.firstElement (); node; node = node.nextElement ())
{
- if (node.nodeType != 1)
- continue;
- if (node.nodeName == 'branch')
+ if (node.nodeName == 'title')
+ state.title = node.firstChild.nodeValue;
+ else
{
- state.keymap.Add (map_list[node.attributes['mname'].nodeValue]);
- state.keymap.actions = Xex.ParseTermList (domain, node.firstChild);
+ var n = node.firstElement ();
+ if (node.nodeName == 'branch')
+ {
+ state.keymap.Add (map_list[node.attributes['mname'].nodeValue]);
+ state.keymap.actions = Xex.Term.Parse (domain, n, null);
+ }
+ else if (node.nodeName == 'state-hook')
+ state.enter_actions = Xex.Term.Parse (domain, n, null);
+ else if (node.nodeName == 'catch-all-branch')
+ state.fallback_actions = Xex.Term.Parse (domain, n, null);
}
- else if (node.nodeName == 'state-hook')
- state.enter_actions = Xex.ParseTermList (domain, node.firstChild);
- else if (node.nodeName == 'catch-all-branch')
- state.fallback_actions = Xex.ParseTermList (domain, node.firstChild);
- else if (node.nodeName == 'title')
- state.title = node.firstChild.nodeValue;
}
return state;
}
}
im_domain.DefSubr (Finsert, "insert", false, 1, 1);
+ im_domain.DefSubr (Finsert_candidates, "insert-candidates", false, 1, 1);
}) ();
(function () {
+ function get_global_var (vname)
+ {
+ if (MIM.im_global.load_status == MIM.LoadStatus.NotLoaded)
+ MIM.im_global.Load ()
+ return MIM.im_global.domain.variables[vname];
+ }
+
var parsers = { };
+
parsers['description'] = function (node)
{
this.description = node.firstChild.nodeValue;
}
- parses['variable-list'] = function (node)
+ parsers['variable-list'] = function (node)
{
- for (node = node.firstChild; node; node = node.nextSibling)
+ for (node = node.firstElement (); node; node = node.nextElement ())
{
- if (node.nodeType != 1)
- continue;
- var name = node.attributes['vname'].nodeValue;
- var vari = get_global_bar (name);
- if (vari != null)
- domain.Defvar (name);
- Xex.Parse (domain, node);
+ var vname = node.attributes['vname'].nodeValue;
+ if (this != MIM.im_global)
+ {
+ var vari = get_global_var (vname);
+ if (vari != null)
+ this.domain.Defvar (vname);
+ }
+ Xex.Term.Parse (this.domain, node);
+ }
+ }
+ parsers['command-list'] = function (node)
+ {
+ }
+ parsers['macro-list'] = function (node)
+ {
+ for (node = node.firstElement (); node; node = node.nextElement ())
+ {
+ if (node.nodeName == 'xi:include')
+ {
+ var im = include (node);
+ if (! im)
+ continue;
+ for (var macro in im.domain.functions)
+ im.domain.CopyFunc (this.domain, macro);
+ }
}
}
parsers['title'] = function (node)
{
if (node.nodeType != 1 || node.nodeName != 'map')
continue;
- var map = Xex.ParseTerm (this.domain, node);
+ var map = Xex.Term.Parse (this.domain, node);
this.map_list[map.name] = map;
}
}
{
if (node.nodeType != 1 || node.nodeName != 'state')
continue;
- var state = Xex.ParseTerm (this.domain, node);
+ var state = Xex.Term.Parse (this.domain, node);
if (! state.title)
state.title = this.title;
if (! this.initial_state)
this.extra_id = extra_id;
this.file = file;
this.load_status = MIM.LoadStatus.NotLoaded;
- this.domain = new Xex.Domain (this.lang + '-' + this.name,
+ this.domain = new Xex.Domain (this.lang + '-'
+ + (this.name != 'nil'
+ ? this.name : this.extra_id),
MIM.im_domain, null);
}
this.map_list = {};
this.initial_state = null;
this.state_list = {};
- for (node = node.firstChild; node; node = node.nextSibling)
+ for (node = node.firstElement (); node; node = node.nextElement ())
{
- if (node.nodeType != 1)
- continue;
var name = node.nodeName;
var parser = parsers[name];
if (parser)
return b.get (this.index - b.Index);
}
- Candidates.prototype.PrevGroup ()
+ Candidates.prototype.PrevGroup = function ()
{
var col = this.Column ();
var nitems;
this.index += this.column - this.Column () + 1;
while (b.Index + b.Count () <= this.index)
b = this.blocks[++this.row];
+ }
}
else
this.index = b.Index + b.Count () - 1;
}
- Candidates.prototype.Select = funciton (selector)
+ Candidates.prototype.Select = function (selector)
{
if (selector instanceof MIM.Selector)
{
for (node = node.firstChild; node; node = node.nextSibling)
if (node.nodeName == 'input-method')
{
- var lang, name, extra_id, file;
+ var lang = null, name = null, extra_id = null, file = null;
for (var n = node.firstChild; n; n = n.nextSibling)
{
else if (n.nodeName == 'filename')
file = n.firstChild.nodeValue;
}
- if (! MIM.im_list[lang])
- MIM.im_list[lang] = {};
- MIM.im_list[lang][name] = new MIM.IM (lang, name, extra_id, file);
+ if (name && name != 'nil')
+ {
+ if (! MIM.imlist[lang])
+ MIM.imlist[lang] = {};
+ MIM.imlist[lang][name] = new MIM.IM (lang, name, extra_id, file);
+ }
+ else if (extra_id && extra_id != 'nil')
+ {
+ if (! MIM.imextra[lang])
+ MIM.imextra[lang] = {};
+ MIM.imextra[lang][extra_id] = new MIM.IM (lang, name, extra_id, file);
+ }
}
+ if (MIM.imextra.t && MIM.imextra.t.global)
+ MIM.im_global = MIM.imextra.t.global;
+ else
+ {
+ MIM.im_global = new MIM.IM ('t', 'nil', 'global', null);
+ MIM.im_global.load_status = MIM.LoadStatus.Error;
+ }
node = undefined;
}) ();
target = target.parentNode;
var idx = 0;
var im = false;
- for (var lang in MIM.im_list)
- for (var name in MIM.im_list[lang])
+ for (var lang in MIM.imlist)
+ for (var name in MIM.imlist[lang])
if (idx++ == target.selectedIndex)
{
- im = MIM.im_list[lang][name];
+ im = MIM.imlist[lang][name];
break;
}
document.getElementsByTagName ('body')[0].removeChild (target);
sel.style.top = (event.clientY - 10) + "px";
sel.target = target;
var idx = 0;
- for (var lang in MIM.im_list)
- for (var name in MIM.im_list[lang])
+ for (var lang in MIM.imlist)
+ for (var name in MIM.imlist[lang])
{
var option = document.createElement ('option');
var imname = lang + "-" + name;
option.appendChild (document.createTextNode (imname));
option.value = imname;
sel.appendChild (option);
- if (MIM.im_list[lang][name] == MIM.current)
+ if (MIM.imlist[lang][name] == MIM.current)
sel.selectedIndex = idx;
idx++;
}
MIM.test = function ()
{
- var im = MIM.im_list['t']['latn-post'];
+ var im = MIM.imlist['t']['latn-post'];
var ic = new MIM.IC (im);
ic.Filter (new MIM.Key ('a'));
else {
try {
document.getElementById ('text').value
- = Xex.ParseTerm (domain, body).Eval (domain).toString ();
+ = Xex.Term.Parse (domain, body).Eval (domain).toString ();
} catch (e) {
if (e instanceof Xex.ErrTerm)
alert (e);
MIM.add_event_listener (window, 'mousedown', MIM.select_menu);
if (window.location == 'http://localhost/mim/index.html')
MIM.server = 'http://localhost/mim';
- MIM.current = MIM.im_list['vi']['telex'];
+ MIM.current = MIM.imlist['vi']['telex'];
};
MIM.init_debug = function ()