calcium-lang
Version:
Calcium language interpreter
110 lines • 4.27 kB
JavaScript
import { default as Sym } from "../symbol";
import { evaluate, retrieveValue } from "../util";
import { createInt, None } from ".";
import { AttributeNotFound, ListIsEmpty } from "../error";
import createBuiltinMethod from "./builtinMethod";
import Slice from "../runtime/slice";
import createIterator from "./iterator";
export default function createList(value) {
let list = value;
const self = new Proxy({}, {
get(target, property, receiver) {
if (property === Sym.evaluate)
return (env) => {
list = list.map((v) => evaluate(v, env));
return self;
};
else if (property === Sym.value)
return list;
else if (property === Sym.class)
return "list";
else if (property === Sym.description) {
return `[${list
.map((v) => {
if (Reflect.get(v, Sym.class) === "str") {
return `'${Reflect.get(v, Sym.description)}'`;
}
else {
return Reflect.get(v, Sym.description);
}
})
.join(", ")}]`;
}
else if (property === Sym.iter) {
return createIterator({
name: "list_iterator",
next: (index) => {
if (index >= list.length)
return null;
else
return list[index];
},
});
}
else if (property === Sym.len)
return createInt(list.length);
else if (property === Sym.slice)
return (lower, upper, value) => {
const slice = new Slice(list);
if (value === undefined) {
return createList(slice.get(lower, upper));
}
else {
slice.set(lower, upper, value);
return None;
}
};
else if (property === Sym.subscript)
return (index, value) => {
let idx = Reflect.get(index, Sym.value);
if (idx < 0)
idx += list.length;
if (value === undefined) {
return list[idx];
}
else {
list[idx] = value;
return None;
}
};
else if (property === "append")
return createBuiltinMethod({
name: "append",
body: (args, env) => {
list.push(evaluate(args[0], env));
return None;
},
});
else if (property === "insert")
return createBuiltinMethod({
name: "insert",
body: (args, env) => {
const index = retrieveValue(args[0], env);
const value = evaluate(args[1], env);
list.splice(index, 0, value);
return None;
},
});
else if (property === "pop")
return createBuiltinMethod({
name: "pop",
body: (args, env) => {
if (args.length === 0) {
const value = list.pop();
if (value === undefined)
throw new ListIsEmpty();
return value;
}
else {
const index = retrieveValue(args[0], env);
const value = list.splice(index, 1)[0];
return value;
}
},
});
throw new AttributeNotFound(property.toString());
},
});
return self;
}
//# sourceMappingURL=list.js.map