calcium-lang
Version:
Calcium language interpreter
127 lines • 3.99 kB
JavaScript
import retrieveValue from "../util/retrieveValue";
import * as Kw from "../keyword";
import { OperationFailed } from "../error";
import { default as Sym } from "../symbol";
import { createBool, createInt, createInternalType, createList, createStr, } from "../factory";
/**
* use a binary operator and calculate
*/
export default class BinaryOperation {
constructor(operator, left, right) {
this.operator = operator;
this.left = left;
this.right = right;
}
[Sym.evaluate](env) {
const valueL = retrieveValue(this.left, env);
const valueR = retrieveValue(this.right, env);
return BinaryOperation.table[this.operator](valueL, valueR);
}
}
BinaryOperation.table = {
[Kw.BinaryOperator.Addition]: (l, r) => {
if (typeof l === "number" && typeof r === "number") {
return createInt(l + r);
}
else if (typeof l === "string" && typeof r === "string") {
return createStr(l + r);
}
else if (Array.isArray(l) && Array.isArray(r)) {
return createList(l.concat(r));
}
else {
throw new OperationFailed();
}
},
[Kw.BinaryOperator.Subtraction]: (l, r) => {
if (typeof l === "number" && typeof r === "number") {
return createInt(l - r);
}
else {
throw new OperationFailed();
}
},
[Kw.BinaryOperator.Multiplication]: (l, r) => {
if (typeof r === "number") {
if (typeof l === "number") {
return createInt(l * r);
}
else if (typeof l === "string") {
return createStr(l.repeat(r));
}
}
throw new OperationFailed();
},
[Kw.BinaryOperator.FloorDivision]: (l, r) => {
if (typeof l === "number" && typeof r === "number") {
return createInt(Math.floor(l / r));
}
else {
throw new OperationFailed();
}
},
[Kw.BinaryOperator.Remainder]: (l, r) => {
if (typeof l === "number" && typeof r === "number") {
return createInt(l % r);
}
else {
throw new OperationFailed();
}
},
[Kw.BinaryOperator.Exponentiation]: (l, r) => {
if (typeof l === "number" && typeof r === "number") {
return createInt(Math.pow(l, r));
}
else {
throw new OperationFailed();
}
},
[Kw.BinaryOperator.Equal]: (l, r) => {
return createBool(l === r);
},
[Kw.BinaryOperator.NotEqual]: (l, r) => {
return createBool(l !== r);
},
[Kw.BinaryOperator.GreaterThan]: (l, r) => {
if (typeof l === "number" && typeof r === "number") {
return createBool(l > r);
}
else if (typeof l === "string" && typeof r === "string") {
return createBool(l > r);
}
else {
throw new OperationFailed();
}
},
[Kw.BinaryOperator.GreaterThanOrEqual]: (l, r) => {
if (typeof l === "number" && typeof r === "number") {
return createBool(l >= r);
}
else if (typeof l === "string" && typeof r === "string") {
return createBool(l >= r);
}
else {
throw new OperationFailed();
}
},
[Kw.BinaryOperator.LessThan]: (l, r) => {
if (typeof l === "number" && typeof r === "number") {
return createBool(l < r);
}
else if (typeof l === "string" && typeof r === "string") {
return createBool(l < r);
}
else {
throw new OperationFailed();
}
},
[Kw.BinaryOperator.And]: (l, r) => {
const result = l && r;
return createInternalType(result);
},
[Kw.BinaryOperator.Or]: (l, r) => {
const result = l || r;
return createInternalType(result);
},
};
//# sourceMappingURL=binaryOperation.js.map