UNPKG

calcium-lang

Version:
127 lines 3.99 kB
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