1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-19 17:47:53 +03:00

rename MalNull to MalNil

This commit is contained in:
vvakame 2017-02-25 14:16:51 +09:00
parent 5bb7479da5
commit 6071876ffe
11 changed files with 65 additions and 57 deletions

View File

@ -2,7 +2,7 @@ import * as fs from "fs";
import { readline } from "./node_readline";
import { Node, MalType, MalSymbol, MalFunction, MalNull, MalList, MalVector, MalBoolean, MalNumber, MalString, MalKeyword, MalHashMap, MalAtom, equals, isSeq } from "./types";
import { Node, MalType, MalSymbol, MalFunction, MalNil, MalList, MalVector, MalBoolean, MalNumber, MalString, MalKeyword, MalHashMap, MalAtom, equals, isSeq } from "./types";
import { readStr } from "./reader";
import { prStr } from "./printer";
@ -16,7 +16,7 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
},
"nil?"(v: MalType) {
return new MalBoolean(v.type === Node.Null);
return new MalBoolean(v.type === Node.Nil);
},
"true?"(v: MalType) {
return new MalBoolean(v.type === Node.Boolean && v.v);
@ -52,15 +52,15 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
"str"(...args: MalType[]): MalString {
return new MalString(args.map(v => prStr(v, false)).join(""));
},
prn(...args: MalType[]): MalNull {
prn(...args: MalType[]): MalNil {
const str = args.map(v => prStr(v, true)).join(" ");
console.log(str);
return MalNull.instance;
return MalNil.instance;
},
println(...args: MalType[]): MalNull {
println(...args: MalType[]): MalNil {
const str = args.map(v => prStr(v, false)).join(" ");
console.log(str);
return MalNull.instance;
return MalNil.instance;
},
"read-string"(v: MalType) {
if (v.type !== Node.String) {
@ -75,7 +75,7 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
const ret = readline(v.v);
if (ret == null) {
return MalNull.instance;
return MalNil.instance;
}
return new MalString(ret);
@ -203,8 +203,8 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
return v.dissoc(args);
},
get(v: MalType, key: MalType) {
if (v.type === Node.Null) {
return MalNull.instance;
if (v.type === Node.Nil) {
return MalNil.instance;
}
if (v.type !== Node.HashMap) {
throw new Error(`unexpected symbol: ${v.type}, expected: hash-map`);
@ -213,11 +213,11 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
throw new Error(`unexpected symbol: ${key.type}, expected: string or keyword`);
}
return v.get(key) || MalNull.instance;
return v.get(key) || MalNil.instance;
},
"contains?"(v: MalType, key: MalType) {
if (v.type === Node.Null) {
return MalNull.instance;
if (v.type === Node.Nil) {
return MalNil.instance;
}
if (v.type !== Node.HashMap) {
throw new Error(`unexpected symbol: ${v.type}, expected: hash-map`);
@ -281,17 +281,17 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
return v;
},
first(v: MalType) {
if (v.type === Node.Null) {
return MalNull.instance;
if (v.type === Node.Nil) {
return MalNil.instance;
}
if (!isSeq(v)) {
throw new Error(`unexpected symbol: ${v.type}, expected: list or vector`);
}
return v.list[0] || MalNull.instance;
return v.list[0] || MalNil.instance;
},
rest(v: MalType) {
if (v.type === Node.Null) {
if (v.type === Node.Nil) {
return new MalList([]);
}
if (!isSeq(v)) {
@ -310,7 +310,7 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
if (isSeq(v)) {
return new MalNumber(v.list.length);
}
if (v.type === Node.Null) {
if (v.type === Node.Nil) {
return new MalNumber(0);
}
throw new Error(`unexpected symbol: ${v.type}`);
@ -353,31 +353,31 @@ export const ns: Map<MalSymbol, MalFunction> = (() => {
seq(v: MalType) {
if (v.type === Node.List) {
if (v.list.length === 0) {
return MalNull.instance;
return MalNil.instance;
}
return v;
}
if (v.type === Node.Vector) {
if (v.list.length === 0) {
return MalNull.instance;
return MalNil.instance;
}
return new MalList(v.list);
}
if (v.type === Node.String) {
if (v.v.length === 0) {
return MalNull.instance;
return MalNil.instance;
}
return new MalList(v.v.split("").map(s => new MalString(s)));
}
if (v.type === Node.Null) {
return MalNull.instance;
if (v.type === Node.Nil) {
return MalNil.instance;
}
throw new Error(`unexpected symbol: ${v.type}, expected: list or vector or string`);
},
meta(v: MalType) {
return v.meta || MalNull.instance;
return v.meta || MalNil.instance;
},
"with-meta"(v: MalType, m: MalType) {
return v.withMeta(m);

View File

@ -30,7 +30,7 @@ export function prStr(v: MalType, printReadably = true): string {
} else {
return v.v;
}
case Node.Null:
case Node.Nil:
return "nil";
case Node.Keyword:
return `:${v.v}`;

View File

@ -1,4 +1,4 @@
import { MalType, MalList, MalString, MalNumber, MalBoolean, MalNull, MalKeyword, MalSymbol, MalVector, MalHashMap } from "./types";
import { MalType, MalList, MalString, MalNumber, MalBoolean, MalNil, MalKeyword, MalSymbol, MalVector, MalHashMap } from "./types";
class Reader {
position = 0;
@ -134,7 +134,7 @@ function readAtom(reader: Reader): MalType {
}
switch (token) {
case "nil":
return MalNull.instance;
return MalNil.instance;
case "true":
return new MalBoolean(true);
case "false":

View File

@ -1,6 +1,6 @@
import { readline } from "./node_readline";
import { Node, MalType, MalNull, MalList, MalVector, MalHashMap, MalFunction, isSeq } from "./types";
import { Node, MalType, MalNil, MalList, MalVector, MalHashMap, MalFunction, isSeq } from "./types";
import { Env } from "./env";
import * as core from "./core";
import { readStr } from "./reader";
@ -91,7 +91,7 @@ function evalMal(ast: MalType, env: Env): MalType {
let b = true;
if (ret.type === Node.Boolean && !ret.v) {
b = false;
} else if (ret.type === Node.Null) {
} else if (ret.type === Node.Nil) {
b = false;
}
if (b) {
@ -99,7 +99,7 @@ function evalMal(ast: MalType, env: Env): MalType {
} else if (elseExrp) {
return evalMal(elseExrp, env);
} else {
return MalNull.instance;
return MalNil.instance;
}
}
case "fn*": {

View File

@ -1,6 +1,6 @@
import { readline } from "./node_readline";
import { Node, MalType, MalNull, MalList, MalVector, MalHashMap, MalFunction, isSeq } from "./types";
import { Node, MalType, MalNil, MalList, MalVector, MalHashMap, MalFunction, isSeq } from "./types";
import { Env } from "./env";
import * as core from "./core";
import { readStr } from "./reader";
@ -91,7 +91,7 @@ function evalMal(ast: MalType, env: Env): MalType {
let b = true;
if (ret.type === Node.Boolean && !ret.v) {
b = false;
} else if (ret.type === Node.Null) {
} else if (ret.type === Node.Nil) {
b = false;
}
if (b) {
@ -99,7 +99,7 @@ function evalMal(ast: MalType, env: Env): MalType {
} else if (elseExrp) {
ast = elseExrp;
} else {
ast = MalNull.instance;
ast = MalNil.instance;
}
continue loop;
}

View File

@ -1,6 +1,6 @@
import { readline } from "./node_readline";
import { Node, MalType, MalString, MalNull, MalList, MalVector, MalHashMap, MalSymbol, MalFunction, isSeq } from "./types";
import { Node, MalType, MalString, MalNil, MalList, MalVector, MalHashMap, MalSymbol, MalFunction, isSeq } from "./types";
import { Env } from "./env";
import * as core from "./core";
import { readStr } from "./reader";
@ -91,7 +91,7 @@ function evalMal(ast: MalType, env: Env): MalType {
let b = true;
if (ret.type === Node.Boolean && !ret.v) {
b = false;
} else if (ret.type === Node.Null) {
} else if (ret.type === Node.Nil) {
b = false;
}
if (b) {
@ -99,7 +99,7 @@ function evalMal(ast: MalType, env: Env): MalType {
} else if (elseExrp) {
ast = elseExrp;
} else {
ast = MalNull.instance;
ast = MalNil.instance;
}
continue loop;
}

View File

@ -1,6 +1,6 @@
import { readline } from "./node_readline";
import { Node, MalType, MalString, MalNull, MalList, MalVector, MalHashMap, MalSymbol, MalFunction, isSeq } from "./types";
import { Node, MalType, MalString, MalNil, MalList, MalVector, MalHashMap, MalSymbol, MalFunction, isSeq } from "./types";
import { Env } from "./env";
import * as core from "./core";
import { readStr } from "./reader";
@ -138,7 +138,7 @@ function evalMal(ast: MalType, env: Env): MalType {
let b = true;
if (ret.type === Node.Boolean && !ret.v) {
b = false;
} else if (ret.type === Node.Null) {
} else if (ret.type === Node.Nil) {
b = false;
}
if (b) {
@ -146,7 +146,7 @@ function evalMal(ast: MalType, env: Env): MalType {
} else if (elseExrp) {
ast = elseExrp;
} else {
ast = MalNull.instance;
ast = MalNil.instance;
}
continue loop;
}

View File

@ -1,6 +1,6 @@
import { readline } from "./node_readline";
import { Node, MalType, MalString, MalNull, MalList, MalVector, MalHashMap, MalSymbol, MalFunction, isSeq } from "./types";
import { Node, MalType, MalString, MalNil, MalList, MalVector, MalHashMap, MalSymbol, MalFunction, isSeq } from "./types";
import { Env } from "./env";
import * as core from "./core";
import { readStr } from "./reader";
@ -202,7 +202,7 @@ function evalMal(ast: MalType, env: Env): MalType {
let b = true;
if (ret.type === Node.Boolean && !ret.v) {
b = false;
} else if (ret.type === Node.Null) {
} else if (ret.type === Node.Nil) {
b = false;
}
if (b) {
@ -210,7 +210,7 @@ function evalMal(ast: MalType, env: Env): MalType {
} else if (elseExrp) {
ast = elseExrp;
} else {
ast = MalNull.instance;
ast = MalNil.instance;
}
continue loop;
}

View File

@ -1,6 +1,6 @@
import { readline } from "./node_readline";
import { Node, MalType, MalString, MalNull, MalList, MalVector, MalHashMap, MalSymbol, MalFunction, isAST, isSeq } from "./types";
import { Node, MalType, MalString, MalNil, MalList, MalVector, MalHashMap, MalSymbol, MalFunction, isAST, isSeq } from "./types";
import { Env } from "./env";
import * as core from "./core";
import { readStr } from "./reader";
@ -224,7 +224,7 @@ function evalMal(ast: MalType, env: Env): MalType {
let b = true;
if (ret.type === Node.Boolean && !ret.v) {
b = false;
} else if (ret.type === Node.Null) {
} else if (ret.type === Node.Nil) {
b = false;
}
if (b) {
@ -232,7 +232,7 @@ function evalMal(ast: MalType, env: Env): MalType {
} else if (elseExrp) {
ast = elseExrp;
} else {
ast = MalNull.instance;
ast = MalNil.instance;
}
continue loop;
}

View File

@ -1,6 +1,6 @@
import { readline } from "./node_readline";
import { Node, MalType, MalString, MalNull, MalList, MalVector, MalHashMap, MalSymbol, MalFunction, isAST, isSeq } from "./types";
import { Node, MalType, MalString, MalNil, MalList, MalVector, MalHashMap, MalSymbol, MalFunction, isAST, isSeq } from "./types";
import { Env } from "./env";
import * as core from "./core";
import { readStr } from "./reader";
@ -224,7 +224,7 @@ function evalMal(ast: MalType, env: Env): MalType {
let b = true;
if (ret.type === Node.Boolean && !ret.v) {
b = false;
} else if (ret.type === Node.Null) {
} else if (ret.type === Node.Nil) {
b = false;
}
if (b) {
@ -232,7 +232,7 @@ function evalMal(ast: MalType, env: Env): MalType {
} else if (elseExrp) {
ast = elseExrp;
} else {
ast = MalNull.instance;
ast = MalNil.instance;
}
continue loop;
}

View File

@ -1,12 +1,12 @@
import { Env } from "./env";
export type MalType = MalList | MalNumber | MalString | MalNull | MalBoolean | MalSymbol | MalKeyword | MalVector | MalHashMap | MalFunction | MalAtom;
export type MalType = MalList | MalNumber | MalString | MalNil | MalBoolean | MalSymbol | MalKeyword | MalVector | MalHashMap | MalFunction | MalAtom;
export const enum Node {
List = 1,
Number,
String,
Null,
Nil,
Boolean,
Symbol,
Keyword,
@ -21,7 +21,7 @@ export function equals(a: MalType, b: MalType, strict?: boolean): boolean {
return false;
}
if (a.type === Node.Null && b.type === Node.Null) {
if (a.type === Node.Nil && b.type === Node.Nil) {
return true;
}
if (isSeq(a) && isSeq(b)) {
@ -39,7 +39,7 @@ export function equals(a: MalType, b: MalType, strict?: boolean): boolean {
throw new Error(`unexpected symbol: ${aK.type}, expected: string or keyword`);
}
const bV = b.get(aK);
if (aV.type === Node.Null && bV.type === Node.Null) {
if (aV.type === Node.Nil && bV.type === Node.Nil) {
continue;
}
if (!equals(aV, bV)) {
@ -124,16 +124,24 @@ export class MalString {
}
}
export class MalNull {
export class MalNil {
static instance = new MalNull();
private static _instance?: MalNil;
type: Node.Null = Node.Null;
static get instance(): MalNil {
if (this._instance) {
return this._instance;
}
this._instance = new MalNil();
return this._instance;
}
type: Node.Nil = Node.Nil;
meta?: MalType;
private constructor() { }
withMeta(_meta: MalType): MalNull {
withMeta(_meta: MalType): MalNil {
throw new Error(`not supported`);
}
}
@ -254,9 +262,9 @@ export class MalHashMap {
get(key: MalKeyword | MalString) {
if (key.type === Node.Keyword) {
return this.keywordMap.get(key) || MalNull.instance;
return this.keywordMap.get(key) || MalNil.instance;
}
return this.stringMap[key.v] || MalNull.instance;
return this.stringMap[key.v] || MalNil.instance;
}
entries(): [MalType, MalType][] {