Spaces:
Running
Running
; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
exports.ValueScope = exports.ValueScopeName = exports.Scope = exports.varKinds = exports.UsedValueState = void 0; | |
const code_1 = require("./code"); | |
class ValueError extends Error { | |
constructor(name) { | |
super(`CodeGen: "code" for ${name} not defined`); | |
this.value = name.value; | |
} | |
} | |
var UsedValueState; | |
(function (UsedValueState) { | |
UsedValueState[UsedValueState["Started"] = 0] = "Started"; | |
UsedValueState[UsedValueState["Completed"] = 1] = "Completed"; | |
})(UsedValueState = exports.UsedValueState || (exports.UsedValueState = {})); | |
exports.varKinds = { | |
const: new code_1.Name("const"), | |
let: new code_1.Name("let"), | |
var: new code_1.Name("var"), | |
}; | |
class Scope { | |
constructor({ prefixes, parent } = {}) { | |
this._names = {}; | |
this._prefixes = prefixes; | |
this._parent = parent; | |
} | |
toName(nameOrPrefix) { | |
return nameOrPrefix instanceof code_1.Name ? nameOrPrefix : this.name(nameOrPrefix); | |
} | |
name(prefix) { | |
return new code_1.Name(this._newName(prefix)); | |
} | |
_newName(prefix) { | |
const ng = this._names[prefix] || this._nameGroup(prefix); | |
return `${prefix}${ng.index++}`; | |
} | |
_nameGroup(prefix) { | |
var _a, _b; | |
if (((_b = (_a = this._parent) === null || _a === void 0 ? void 0 : _a._prefixes) === null || _b === void 0 ? void 0 : _b.has(prefix)) || (this._prefixes && !this._prefixes.has(prefix))) { | |
throw new Error(`CodeGen: prefix "${prefix}" is not allowed in this scope`); | |
} | |
return (this._names[prefix] = { prefix, index: 0 }); | |
} | |
} | |
exports.Scope = Scope; | |
class ValueScopeName extends code_1.Name { | |
constructor(prefix, nameStr) { | |
super(nameStr); | |
this.prefix = prefix; | |
} | |
setValue(value, { property, itemIndex }) { | |
this.value = value; | |
this.scopePath = (0, code_1._) `.${new code_1.Name(property)}[${itemIndex}]`; | |
} | |
} | |
exports.ValueScopeName = ValueScopeName; | |
const line = (0, code_1._) `\n`; | |
class ValueScope extends Scope { | |
constructor(opts) { | |
super(opts); | |
this._values = {}; | |
this._scope = opts.scope; | |
this.opts = { ...opts, _n: opts.lines ? line : code_1.nil }; | |
} | |
get() { | |
return this._scope; | |
} | |
name(prefix) { | |
return new ValueScopeName(prefix, this._newName(prefix)); | |
} | |
value(nameOrPrefix, value) { | |
var _a; | |
if (value.ref === undefined) | |
throw new Error("CodeGen: ref must be passed in value"); | |
const name = this.toName(nameOrPrefix); | |
const { prefix } = name; | |
const valueKey = (_a = value.key) !== null && _a !== void 0 ? _a : value.ref; | |
let vs = this._values[prefix]; | |
if (vs) { | |
const _name = vs.get(valueKey); | |
if (_name) | |
return _name; | |
} | |
else { | |
vs = this._values[prefix] = new Map(); | |
} | |
vs.set(valueKey, name); | |
const s = this._scope[prefix] || (this._scope[prefix] = []); | |
const itemIndex = s.length; | |
s[itemIndex] = value.ref; | |
name.setValue(value, { property: prefix, itemIndex }); | |
return name; | |
} | |
getValue(prefix, keyOrRef) { | |
const vs = this._values[prefix]; | |
if (!vs) | |
return; | |
return vs.get(keyOrRef); | |
} | |
scopeRefs(scopeName, values = this._values) { | |
return this._reduceValues(values, (name) => { | |
if (name.scopePath === undefined) | |
throw new Error(`CodeGen: name "${name}" has no value`); | |
return (0, code_1._) `${scopeName}${name.scopePath}`; | |
}); | |
} | |
scopeCode(values = this._values, usedValues, getCode) { | |
return this._reduceValues(values, (name) => { | |
if (name.value === undefined) | |
throw new Error(`CodeGen: name "${name}" has no value`); | |
return name.value.code; | |
}, usedValues, getCode); | |
} | |
_reduceValues(values, valueCode, usedValues = {}, getCode) { | |
let code = code_1.nil; | |
for (const prefix in values) { | |
const vs = values[prefix]; | |
if (!vs) | |
continue; | |
const nameSet = (usedValues[prefix] = usedValues[prefix] || new Map()); | |
vs.forEach((name) => { | |
if (nameSet.has(name)) | |
return; | |
nameSet.set(name, UsedValueState.Started); | |
let c = valueCode(name); | |
if (c) { | |
const def = this.opts.es5 ? exports.varKinds.var : exports.varKinds.const; | |
code = (0, code_1._) `${code}${def} ${name} = ${c};${this.opts._n}`; | |
} | |
else if ((c = getCode === null || getCode === void 0 ? void 0 : getCode(name))) { | |
code = (0, code_1._) `${code}${c}${this.opts._n}`; | |
} | |
else { | |
throw new ValueError(name); | |
} | |
nameSet.set(name, UsedValueState.Completed); | |
}); | |
} | |
return code; | |
} | |
} | |
exports.ValueScope = ValueScope; | |
//# sourceMappingURL=scope.js.map |