-
Notifications
You must be signed in to change notification settings - Fork 1
/
concrete.js
105 lines (89 loc) · 2.67 KB
/
concrete.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import * as es6 from './es6';
import { Environment } from './env';
import { Pointer } from './pointer';
import { warn_unimplemented } from './utils';
// concrete values
class CVal {
constructor(val) {
this._val = val;
}
get value() { return this._val; }
toString() { return `CVal(${this.value})`; }
}
let _cbool_false;
let _cbool_true;
export class CBool extends CVal {
constructor(val) {
super(val);
}
static get False() { return _cbool_false; }
static get True() { return _cbool_true; }
toString() { return `CBool(${this.value})`; }
}
_cbool_false = new CBool(false);
_cbool_true = new CBool(true);
export class CObject extends CVal {
constructor(proto_addr, store) {
let proto = es6.GetValue(proto_addr, store);
super(Object.create(null));
this._proto = proto_addr;
this._env = new Environment(proto.value ? proto.value._env : null);
this._env.setOffset('__proto__', proto_addr);
}
get proto() { return this._proto; }
set(key, value, store) {
if (value instanceof Pointer) {
this._env.setOffset(key.value, value);
}
else {
warn_unimplemented(`CObject.set(${key.toString()},${value.toString()})`);
}
}
get(key, store) {
// we assume that key is a CVal subclass here
let off = this._env.getOffset(key.value, false);
if (off !== -1) return off;
// the object didn't have that property, so we add it to the local env
return this._env.offset(key.value);
}
toString() { return 'CObject'; }
}
export class CArray extends CObject {
constructor(val) {
super(val);
}
toString() { return 'CArray'; }
}
export class CFunction extends CVal /* CObject */ {
constructor(val) {
super(val);
}
toString() { return `CFunction ${this.value.id ? this.value.id.name : 'anon'}`; }
}
export class CNum extends CVal {
constructor(num) { super(num); }
toString() { return `CNum(${this.value})`; }
}
export class CStr extends CVal {
constructor(str) { super(str); }
toString() { return `CStr(${this.value})`; }
}
export class CSym extends CVal {
constructor(sym) { super(sym); }
toString() { return `CStr(${this.value})`; }
}
export class CNull extends CVal {
constructor() { super(null); }
toString() { return 'CNull()'; }
}
export class CUndefined extends CVal {
constructor() { super(undefined); }
toString() { return 'CUndefined()'; }
}
export class CBuiltinFunc extends CVal {
constructor(arity, fun) {
super(fun);
this._arity = arity;
}
toString() { return `CBuiltinFunc(${this._arity}, ${this.value})`; }
}