1
1
mirror of https://github.com/kanaka/mal.git synced 2024-11-11 00:52:44 +03:00

reordering core.ns

This commit is contained in:
vvakame 2017-02-25 13:03:04 +09:00
parent 9c92462f39
commit 12c0c9a3a8

View File

@ -8,18 +8,44 @@ import { prStr } from "./printer";
export const ns: Map<MalSymbol, MalFunction> = (() => {
const ns: { [symbol: string]: typeof MalFunction.prototype.func; } = {
readline(v: MalType) {
"="(a: MalType, b: MalType): MalBoolean {
return new MalBoolean(equals(a, b));
},
throw(v: MalType): MalType {
throw v;
},
"nil?"(v: MalType) {
return new MalBoolean(MalNull.is(v));
},
"true?"(v: MalType) {
return new MalBoolean(MalBoolean.is(v) && v.v);
},
"false?"(v: MalType) {
return new MalBoolean(MalBoolean.is(v) && !v.v);
},
"string?"(v: MalType) {
return new MalBoolean(MalString.is(v));
},
symbol(v: MalType) {
if (!MalString.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: string`);
}
const ret = readline(v.v);
if (ret == null) {
return MalNull.instance;
}
return new MalString(ret);
return MalSymbol.get(v.v);
},
"symbol?"(v: MalType) {
return new MalBoolean(MalSymbol.is(v));
},
keyword(v: MalType) {
if (!MalString.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: string`);
}
return MalKeyword.get(v.v);
},
"keyword?"(v: MalType) {
return new MalBoolean(MalKeyword.is(v));
},
"pr-str"(...args: MalType[]): MalString {
return new MalString(args.map(v => prStr(v, true)).join(" "));
},
@ -42,6 +68,18 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
}
return readStr(v.v);
},
readline(v: MalType) {
if (!MalString.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: string`);
}
const ret = readline(v.v);
if (ret == null) {
return MalNull.instance;
}
return new MalString(ret);
},
slurp(v: MalType) {
if (!MalString.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: string`);
@ -49,134 +87,46 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
const content = fs.readFileSync(v.v, "UTF-8");
return new MalString(content);
},
cons(a: MalType, b: MalType) {
if (!MalList.is(b) && !MalVector.is(b)) {
throw new Error(`unexpected symbol: ${b.type}, expected: list or vector`);
"<"(a: MalType, b: MalType): MalBoolean {
if (!MalNumber.is(a)) {
throw new Error(`unexpected symbol: ${a.type}, expected: number`);
}
if (!MalNumber.is(b)) {
throw new Error(`unexpected symbol: ${b.type}, expected: number`);
}
return new MalList([a].concat(b.list));
return new MalBoolean(a.v < b.v);
},
concat(...args: MalType[]) {
const list = args
.map(arg => {
if (!MalList.is(arg) && !MalVector.is(arg)) {
throw new Error(`unexpected symbol: ${arg.type}, expected: list or vector`);
}
return arg;
})
.reduce((p, c) => p.concat(c.list), [] as MalType[]);
return new MalList(list);
},
list(...args: MalType[]): MalList {
return new MalList(args);
},
"list?"(v: MalType): MalBoolean {
return new MalBoolean(v instanceof MalList);
},
"empty?"(v: MalType): MalBoolean {
if (!MalList.is(v) && !MalVector.is(v)) {
return new MalBoolean(false);
"<="(a: MalType, b: MalType): MalBoolean {
if (!MalNumber.is(a)) {
throw new Error(`unexpected symbol: ${a.type}, expected: number`);
}
return new MalBoolean(v.list.length === 0);
},
count(v: MalType): MalNumber {
if (MalList.is(v) || MalVector.is(v)) {
return new MalNumber(v.list.length);
}
if (MalNull.is(v)) {
return new MalNumber(0);
}
throw new Error(`unexpected symbol: ${v.type}`);
},
nth(list: MalType, idx: MalType) {
if (!MalList.is(list) && !MalVector.is(list)) {
throw new Error(`unexpected symbol: ${list.type}, expected: list or vector`);
}
if (!MalNumber.is(idx)) {
throw new Error(`unexpected symbol: ${idx.type}, expected: number`);
if (!MalNumber.is(b)) {
throw new Error(`unexpected symbol: ${b.type}, expected: number`);
}
const v = list.list[idx.v];
if (!v) {
throw new Error("nth: index out of range");
return new MalBoolean(a.v <= b.v);
},
">"(a: MalType, b: MalType): MalBoolean {
if (!MalNumber.is(a)) {
throw new Error(`unexpected symbol: ${a.type}, expected: number`);
}
if (!MalNumber.is(b)) {
throw new Error(`unexpected symbol: ${b.type}, expected: number`);
}
return v;
return new MalBoolean(a.v > b.v);
},
first(v: MalType) {
if (MalNull.is(v)) {
return MalNull.instance;
">="(a: MalType, b: MalType): MalBoolean {
if (!MalNumber.is(a)) {
throw new Error(`unexpected symbol: ${a.type}, expected: number`);
}
if (!MalList.is(v) && !MalVector.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: list or vector`);
if (!MalNumber.is(b)) {
throw new Error(`unexpected symbol: ${b.type}, expected: number`);
}
return v.list[0] || MalNull.instance;
},
rest(v: MalType) {
if (MalNull.is(v)) {
return new MalList([]);
}
if (!MalList.is(v) && !MalVector.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: list or vector`);
}
return new MalList(v.list.slice(1));
},
atom(v: MalType): MalAtom {
return new MalAtom(v);
},
"atom?"(v: MalType): MalBoolean {
return new MalBoolean(MalAtom.is(v));
},
deref(v: MalType): MalType {
if (!MalAtom.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: atom`);
}
return v.v;
},
"reset!"(atom: MalType, v: MalType): MalType {
if (!MalAtom.is(atom)) {
throw new Error(`unexpected symbol: ${atom.type}, expected: atom`);
}
atom.v = v;
return v;
},
"swap!"(atom: MalType, f: MalType, ...args: MalType[]): MalType {
if (!MalAtom.is(atom)) {
throw new Error(`unexpected symbol: ${atom.type}, expected: atom`);
}
if (!MalFunction.is(f)) {
throw new Error(`unexpected symbol: ${f.type}, expected: function`);
}
atom.v = f.func(...[atom.v].concat(args));
return atom.v;
},
throw(v: MalType): MalType {
throw v;
},
apply(f: MalType, ...list: MalType[]) {
if (!MalFunction.is(f)) {
throw new Error(`unexpected symbol: ${f.type}, expected: function`);
}
const tail = list[list.length - 1];
if (!MalList.is(tail) && !MalVector.is(tail)) {
throw new Error(`unexpected symbol: ${tail.type}, expected: list or vector`);
}
const args = list.slice(0, -1).concat(tail.list);
return f.func(...args);
},
map(f: MalType, list: MalType) {
if (!MalFunction.is(f)) {
throw new Error(`unexpected symbol: ${f.type}, expected: function`);
}
if (!MalList.is(list) && !MalVector.is(list)) {
throw new Error(`unexpected symbol: ${list.type}, expected: list or vector`);
}
return new MalList(list.list.map(v => f.func(v)));
return new MalBoolean(a.v >= b.v);
},
"+"(a: MalType, b: MalType): MalNumber {
if (!MalNumber.is(a)) {
@ -218,81 +168,15 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
return new MalNumber(a.v / b.v);
},
"="(a: MalType, b: MalType): MalBoolean {
return new MalBoolean(equals(a, b));
},
"<"(a: MalType, b: MalType): MalBoolean {
if (!MalNumber.is(a)) {
throw new Error(`unexpected symbol: ${a.type}, expected: number`);
}
if (!MalNumber.is(b)) {
throw new Error(`unexpected symbol: ${b.type}, expected: number`);
}
return new MalBoolean(a.v < b.v);
},
"<="(a: MalType, b: MalType): MalBoolean {
if (!MalNumber.is(a)) {
throw new Error(`unexpected symbol: ${a.type}, expected: number`);
}
if (!MalNumber.is(b)) {
throw new Error(`unexpected symbol: ${b.type}, expected: number`);
}
return new MalBoolean(a.v <= b.v);
},
">"(a: MalType, b: MalType): MalBoolean {
if (!MalNumber.is(a)) {
throw new Error(`unexpected symbol: ${a.type}, expected: number`);
}
if (!MalNumber.is(b)) {
throw new Error(`unexpected symbol: ${b.type}, expected: number`);
}
return new MalBoolean(a.v > b.v);
},
">="(a: MalType, b: MalType): MalBoolean {
if (!MalNumber.is(a)) {
throw new Error(`unexpected symbol: ${a.type}, expected: number`);
}
if (!MalNumber.is(b)) {
throw new Error(`unexpected symbol: ${b.type}, expected: number`);
}
return new MalBoolean(a.v >= b.v);
},
"time-ms"() {
return new MalNumber(Date.now());
},
"nil?"(v: MalType) {
return new MalBoolean(MalNull.is(v));
list(...args: MalType[]): MalList {
return new MalList(args);
},
"true?"(v: MalType) {
return new MalBoolean(MalBoolean.is(v) && v.v);
},
"false?"(v: MalType) {
return new MalBoolean(MalBoolean.is(v) && !v.v);
},
"string?"(v: MalType) {
return new MalBoolean(MalString.is(v));
},
"symbol?"(v: MalType) {
return new MalBoolean(MalSymbol.is(v));
},
symbol(v: MalType) {
if (!MalString.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: string`);
}
return MalSymbol.get(v.v);
},
keyword(v: MalType) {
if (!MalString.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: string`);
}
return MalKeyword.get(v.v);
},
"keyword?"(v: MalType) {
return new MalBoolean(MalKeyword.is(v));
"list?"(v: MalType): MalBoolean {
return new MalBoolean(v instanceof MalList);
},
vector(...args: MalType[]): MalVector {
return new MalVector(args);
@ -358,9 +242,102 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
return new MalList([...v.vals()]);
},
"sequential?"(v: MalType) {
return new MalBoolean(MalList.is(v) || MalVector.is(v));
},
cons(a: MalType, b: MalType) {
if (!MalList.is(b) && !MalVector.is(b)) {
throw new Error(`unexpected symbol: ${b.type}, expected: list or vector`);
}
return new MalList([a].concat(b.list));
},
concat(...args: MalType[]) {
const list = args
.map(arg => {
if (!MalList.is(arg) && !MalVector.is(arg)) {
throw new Error(`unexpected symbol: ${arg.type}, expected: list or vector`);
}
return arg;
})
.reduce((p, c) => p.concat(c.list), [] as MalType[]);
return new MalList(list);
},
nth(list: MalType, idx: MalType) {
if (!MalList.is(list) && !MalVector.is(list)) {
throw new Error(`unexpected symbol: ${list.type}, expected: list or vector`);
}
if (!MalNumber.is(idx)) {
throw new Error(`unexpected symbol: ${idx.type}, expected: number`);
}
const v = list.list[idx.v];
if (!v) {
throw new Error("nth: index out of range");
}
return v;
},
first(v: MalType) {
if (MalNull.is(v)) {
return MalNull.instance;
}
if (!MalList.is(v) && !MalVector.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: list or vector`);
}
return v.list[0] || MalNull.instance;
},
rest(v: MalType) {
if (MalNull.is(v)) {
return new MalList([]);
}
if (!MalList.is(v) && !MalVector.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: list or vector`);
}
return new MalList(v.list.slice(1));
},
"empty?"(v: MalType): MalBoolean {
if (!MalList.is(v) && !MalVector.is(v)) {
return new MalBoolean(false);
}
return new MalBoolean(v.list.length === 0);
},
count(v: MalType): MalNumber {
if (MalList.is(v) || MalVector.is(v)) {
return new MalNumber(v.list.length);
}
if (MalNull.is(v)) {
return new MalNumber(0);
}
throw new Error(`unexpected symbol: ${v.type}`);
},
apply(f: MalType, ...list: MalType[]) {
if (!MalFunction.is(f)) {
throw new Error(`unexpected symbol: ${f.type}, expected: function`);
}
const tail = list[list.length - 1];
if (!MalList.is(tail) && !MalVector.is(tail)) {
throw new Error(`unexpected symbol: ${tail.type}, expected: list or vector`);
}
const args = list.slice(0, -1).concat(tail.list);
return f.func(...args);
},
map(f: MalType, list: MalType) {
if (!MalFunction.is(f)) {
throw new Error(`unexpected symbol: ${f.type}, expected: function`);
}
if (!MalList.is(list) && !MalVector.is(list)) {
throw new Error(`unexpected symbol: ${list.type}, expected: list or vector`);
}
return new MalList(list.list.map(v => f.func(v)));
},
conj(list: MalType, ...args: MalType[]) {
switch (list.type) {
case "list":
@ -398,11 +375,41 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
throw new Error(`unexpected symbol: ${v.type}, expected: list or vector or string`);
},
meta(v: MalType) {
return v.meta || MalNull.instance;
},
"with-meta"(v: MalType, m: MalType) {
return v.withMeta(m);
},
meta(v: MalType) {
return v.meta || MalNull.instance;
atom(v: MalType): MalAtom {
return new MalAtom(v);
},
"atom?"(v: MalType): MalBoolean {
return new MalBoolean(MalAtom.is(v));
},
deref(v: MalType): MalType {
if (!MalAtom.is(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: atom`);
}
return v.v;
},
"reset!"(atom: MalType, v: MalType): MalType {
if (!MalAtom.is(atom)) {
throw new Error(`unexpected symbol: ${atom.type}, expected: atom`);
}
atom.v = v;
return v;
},
"swap!"(atom: MalType, f: MalType, ...args: MalType[]): MalType {
if (!MalAtom.is(atom)) {
throw new Error(`unexpected symbol: ${atom.type}, expected: atom`);
}
if (!MalFunction.is(f)) {
throw new Error(`unexpected symbol: ${f.type}, expected: function`);
}
atom.v = f.func(...[atom.v].concat(args));
return atom.v;
},
};