Skip to content

Instantly share code, notes, and snippets.

@levjj levjj/sweet-units.sjs
Last active Aug 29, 2015

Embed
What would you like to do?
Units of measure with sweet.js
// Some minimal class for values with units
// (nothing exciting going on...)
function Unit(name,val) {
this.name = name;
this.val = val;
}
Unit.prototype.toString = function() {
return this.val + " " + this.name;
}
Unit.prototype.add = function(other) {
if ("number" == typeof other) return new Unit(this.name, this.val + other);
if (other.name != this.name) throw new Error("does not work");
return new Unit(this.name, this.val + other.val);
}
Unit.prototype.times = function(other) {
if ("number" == typeof other) return new Unit(this.name, this.val * other);
if (other.name != this.name) throw new Error("does not work");
return new Unit(this.name, this.val * other.val);
}
Unit.prototype.lessThan = function(other) {
if ("number" == typeof other) return this.val < other;
if (other.name != this.name) throw new Error("does not work");
return this.val < other.val;
}
// How to define new units
// You can have basic SI units or derived units.
macro unit {
rule { $name = $r:expr } => {
macro $name {
rule infix {$x:expr |} => { ($r).times($x) }
}
}
rule { $name } => {
macro $name {
case infix {$x:expr | $name} => {
var name = #{$name};
var nom = name[0].token.value;
return withSyntax($nlit = [makeValue(nom,name)]) {
return #{new Unit($nlit, $x)}
}
}
}
}
}
// Adding some syntactic sugar
// (Using "++" so we don't lose native "+")
macro ++ { rule infix { $x:expr | $y:expr } => { $x.add($y) } }
macro << { rule infix { $x:expr | $y:expr } => { $x.lessThan($y) } }
// Now, let's define some units!
unit m;
unit km = 1000 m;
unit mile = 1609 m;
unit miles = 1 mile;
unit s;
unit min = 60 s;
unit h = 60 min;
unit day = 24 h;
// And here you can use them:
alert(2 miles);
alert(1.5 km ++ 100 m);
alert(2 miles << 10 km);
alert(1 day << 23 h ++ 70 min);
var todos = [30 min, 2 h, 45 min, 2.5 h, 30 min];
var done = 0 min;
while (done << 5 h) {
done = done ++ todos.shift();
}
alert("Not enough time to finish: " + todos);
// Hint: Paste this file into http://sweetjs.org/browser/editor.html to try it out!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.