Skip to content
Permalink
Browse files

add Numbas.jme.tokenComparisons

Numbas.jme.compareTokens now has a dictionary of comparison functions,
so extensions which add data types can make them comparable.
  • Loading branch information...
christianp committed Aug 1, 2018
1 parent 2093200 commit 8605e71cacaae397ffcb3a9dbc92bc3d9d1b3922
Showing with 90 additions and 21 deletions.
  1. +24 −7 runtime/scripts/jme.js
  2. +6 −0 runtime/scripts/util.js
  3. +30 −7 tests/jme-runtime.js
  4. +30 −7 tests/numbas-runtime.js
@@ -2219,24 +2219,41 @@ var varsUsed = jme.varsUsed = function(tree) {
}
};

/** Use JS comparison operators to compare the `value` property of both tokens.
* Used when the token wraps a JS built-in type, such as string, number or boolean.
* @see @Numbas.jme.tokenComparisons
*/
var compareTokensByValue = jme.compareTokensByValue = function(a,b) {
return a.value>b.value ? 1 : a.value<b.value ? -1 : 0;
}

/** Functions to compare two tokens of the same type.
* Returns -1 if a<b, 0 if a=b, and 1 if a>b
* @see Numbas.jme.compareTokens
*/
var tokenComparisons = Numbas.jme.tokenComparisons = {
'number': compareTokensByValue,
'string': compareTokensByValue,
'boolean': compareTokensByValue
}

/** Compare two tokens, for the purposes of sorting.
* Uses JavaScript comparison for numbers, strings and booleans, and {@link Numbas.jme.compareTrees} for everything else, or when types differ.
*
* @param {Numbas.jme.token} a
* @param {Numbas.jme.token} b
* @see Numbas.jme.tokenComparisons
* @returns {Number} -1 if `a < b`, 1 if `a > b`, else 0.
*/
var compareTokens = jme.compareTokens = function(a,b) {
if(a.type!=b.type) {
return jme.compareTrees({tok:a},{tok:b});
} else {
switch(a.type) {
case 'number':
case 'string':
case 'boolean':
return a.value>b.value ? 1 : a.value<b.value ? -1 : 0;
default:
return jme.compareTrees({tok:a},{tok:b});
var compare = tokenComparisons[a.type];
if(compare) {
return compare(a,b);
} else {
return jme.compareTrees({tok:a},{tok:b});
}
}
}
@@ -133,6 +133,7 @@ var util = Numbas.util = /** @lends Numbas.util */ {
/** Generic equality test on {@link Numbas.jme.token}s
* @param {Numbas.jme.token} a
* @param {Numbas.jme.token} b
* @see Numbas.util.equalityTests
* @returns {Boolean}
*/
eq: function(a,b) {
@@ -144,6 +145,11 @@ var util = Numbas.util = /** @lends Numbas.util */ {
throw(new Numbas.Error('util.equality not defined for type',{type:a.type}));
}
},

/** Functions to decide if two tokens of the same type are equal.
* Dictionary mapping token type name to function.
* @see Numbas.util.eq
*/
equalityTests: {
'nothing': function(a,b) {
return true;
@@ -365,6 +365,7 @@ var util = Numbas.util = /** @lends Numbas.util */ {
/** Generic equality test on {@link Numbas.jme.token}s
* @param {Numbas.jme.token} a
* @param {Numbas.jme.token} b
* @see Numbas.util.equalityTests
* @returns {Boolean}
*/
eq: function(a,b) {
@@ -376,6 +377,11 @@ var util = Numbas.util = /** @lends Numbas.util */ {
throw(new Numbas.Error('util.equality not defined for type',{type:a.type}));
}
},

/** Functions to decide if two tokens of the same type are equal.
* Dictionary mapping token type name to function.
* @see Numbas.util.eq
*/
equalityTests: {
'nothing': function(a,b) {
return true;
@@ -7655,24 +7661,41 @@ var varsUsed = jme.varsUsed = function(tree) {
}
};

/** Use JS comparison operators to compare the `value` property of both tokens.
* Used when the token wraps a JS built-in type, such as string, number or boolean.
* @see @Numbas.jme.tokenComparisons
*/
var compareTokensByValue = jme.compareTokensByValue = function(a,b) {
return a.value>b.value ? 1 : a.value<b.value ? -1 : 0;
}

/** Functions to compare two tokens of the same type.
* Returns -1 if a<b, 0 if a=b, and 1 if a>b
* @see Numbas.jme.compareTokens
*/
var tokenComparisons = Numbas.jme.tokenComparisons = {
'number': compareTokensByValue,
'string': compareTokensByValue,
'boolean': compareTokensByValue
}

/** Compare two tokens, for the purposes of sorting.
* Uses JavaScript comparison for numbers, strings and booleans, and {@link Numbas.jme.compareTrees} for everything else, or when types differ.
*
* @param {Numbas.jme.token} a
* @param {Numbas.jme.token} b
* @see Numbas.jme.tokenComparisons
* @returns {Number} -1 if `a < b`, 1 if `a > b`, else 0.
*/
var compareTokens = jme.compareTokens = function(a,b) {
if(a.type!=b.type) {
return jme.compareTrees({tok:a},{tok:b});
} else {
switch(a.type) {
case 'number':
case 'string':
case 'boolean':
return a.value>b.value ? 1 : a.value<b.value ? -1 : 0;
default:
return jme.compareTrees({tok:a},{tok:b});
var compare = tokenComparisons[a.type];
if(compare) {
return compare(a,b);
} else {
return jme.compareTrees({tok:a},{tok:b});
}
}
}
@@ -365,6 +365,7 @@ var util = Numbas.util = /** @lends Numbas.util */ {
/** Generic equality test on {@link Numbas.jme.token}s
* @param {Numbas.jme.token} a
* @param {Numbas.jme.token} b
* @see Numbas.util.equalityTests
* @returns {Boolean}
*/
eq: function(a,b) {
@@ -376,6 +377,11 @@ var util = Numbas.util = /** @lends Numbas.util */ {
throw(new Numbas.Error('util.equality not defined for type',{type:a.type}));
}
},

/** Functions to decide if two tokens of the same type are equal.
* Dictionary mapping token type name to function.
* @see Numbas.util.eq
*/
equalityTests: {
'nothing': function(a,b) {
return true;
@@ -7655,24 +7661,41 @@ var varsUsed = jme.varsUsed = function(tree) {
}
};

/** Use JS comparison operators to compare the `value` property of both tokens.
* Used when the token wraps a JS built-in type, such as string, number or boolean.
* @see @Numbas.jme.tokenComparisons
*/
var compareTokensByValue = jme.compareTokensByValue = function(a,b) {
return a.value>b.value ? 1 : a.value<b.value ? -1 : 0;
}

/** Functions to compare two tokens of the same type.
* Returns -1 if a<b, 0 if a=b, and 1 if a>b
* @see Numbas.jme.compareTokens
*/
var tokenComparisons = Numbas.jme.tokenComparisons = {
'number': compareTokensByValue,
'string': compareTokensByValue,
'boolean': compareTokensByValue
}

/** Compare two tokens, for the purposes of sorting.
* Uses JavaScript comparison for numbers, strings and booleans, and {@link Numbas.jme.compareTrees} for everything else, or when types differ.
*
* @param {Numbas.jme.token} a
* @param {Numbas.jme.token} b
* @see Numbas.jme.tokenComparisons
* @returns {Number} -1 if `a < b`, 1 if `a > b`, else 0.
*/
var compareTokens = jme.compareTokens = function(a,b) {
if(a.type!=b.type) {
return jme.compareTrees({tok:a},{tok:b});
} else {
switch(a.type) {
case 'number':
case 'string':
case 'boolean':
return a.value>b.value ? 1 : a.value<b.value ? -1 : 0;
default:
return jme.compareTrees({tok:a},{tok:b});
var compare = tokenComparisons[a.type];
if(compare) {
return compare(a,b);
} else {
return jme.compareTrees({tok:a},{tok:b});
}
}
}

0 comments on commit 8605e71

Please sign in to comment.
You can’t perform that action at this time.