An experiment in parentheses-free lisp (in JavaScript)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

162 lines
2.8 KiB

var Expression = {
display :
function() {
return this.exprType + " " + this.val;
},
type :
function () {
return this.exprType;
},
unify :
function (t) {
if (this.exprType === t.exprType) {
return t.exprType;
}
else {
console.log("Could not unify " + this.exprType + " with " + t.exprType);
}
}
};
function IntT(v) {
this.exprType = "Integer";
this.val = parseInt(v, 10);
return this;
}
IntT.prototype = Expression;
function FloatT(v) {
this.exprType = "Float";
this.val = parseFloat(v, 10);
return this;
}
FloatT.prototype = Expression;
function StrT(v) {
this.exprType = "String";
this.val = v;
return this;
}
StrT.prototype = Expression;
function BoolT(b) {
if (b === "true") {
this.val = true;
}
else {
this.val = false;
}
this.exprType = "Bool";
return this;
}
BoolT.prototype = Expression;
function ListT(x, xs) {
this.x = x;
this.rest = xs;
this.val = [x,xs];
this.exprType = "List";
return this;
}
ListT.prototype = Expression;
function FuncT(p, body) {
this.p = p;
this.body = body;
this.val = [p, body];
this.exprType = "Function";
return this;
}
FuncT.prototype = Expression;
//Wrapper for function objects
function OpT(operator) {
this.op = operator;
this.val = this.op;
this.exprType = "Function";
return this;
}
OpT.prototype = Expression;
// Applications separate from other types
function App(func, p) {
this.func = func;
this.exprType = "Application";
if (p)
this.p = p;
return this;
}
// Names are not types
function Name(identifier) {
this.ident = identifier;
this.val = this.ident;
this.exprType = "Name";
return this;
}
function Def(ident, exp) {
this.ident = ident;
this.val = exp;
this.exprType = "Definition";
return this;
}
function If(condition, thenexp, elseexp) {
this.condition = condition;
this.thenexp = thenexp;
if (elseexp)
this.elseexp = elseexp;
this.exprType = "If";
return this;
}
//convenience function to construct binary operators
//assumes that the identifier refers to the name of a primitive
//operation
function makeBin(ident) {
return new OpT(new FuncT (new Name("a"), new FuncT(new Name("b"), new App(new App(ident, "a"), "b"))));
}
//Applies the function ``name'' to the list of parameters
function makeApp(name, parameters) {
if (parameters) {
return parameters.slice(1).reduce(function(f, ident) {
return new App(f, ident);
}, new App(name, parameters[0]));
}
else {
return new App(name);
}
}
OPTable = {"+" : makeBin("+")};
OPInfo = {"+" : [1, "Left"],
"-" : [1, "Left"],
"*" : [2, "Left"],
"/" : [2, "Left"],
"^" : [3, "Right"]}
module.exports =
{ IntT : IntT,
FloatT : FloatT,
StrT : StrT,
BoolT : BoolT,
ListT : ListT,
FuncT : FuncT,
App : App,
Name : Name,
Def : Def,
OpT : OpT,
OPInfo : OPInfo,
makeApp : makeApp,
If : If}