UNPKG

expexp

Version:

The express model io and express model and data representation.

81 lines (70 loc) 2.22 kB
// Provides a scope with variable names to lookup values and query whether // a given value is by copy or by reference. // Variable scope is hierarical, meaning that there can be a parent scope given // on construction. That if any lookup on the current scope fails, the parent // scope is tried for instead. // There are two different notions about setting a value: First a value and its // type model must be registered. This can only happen once and only for the // current scope - not for the parent. On the other hand a value can be set // several times and if declared as 'by reference' (proc VAR) setting can also // affect the value in the parents scope. It is not up to this class to check // if a value is valid to be set for a given name or type model. export function VariableScope(parent) { const me = {} const c = {} // name cache const BY_VAL = -1 const r = {} // reference index (or -1 if not a reference - mostly the case) const setup = function() { // nothing to do } // Register a value. // If a value is by reference (onyl case: procedure var param) value is always // an array and isRefIdx says what position the actual value has within that array. // Like that an entites attrValues might be passed (infrastructure array) as // value or a data arrays position. me.regVal = function(name, value, isRefIdx = -1) { c[name] = value r[name] = isRefIdx } me.has = function(name) { if (name in c) { return true } else if (parent) { return parent.has(name) } else { return false } } me.get = function(name) { if (name in c) { if (r[name] == BY_VAL) { return c[name] } else { // by reference (var) return getByRef(name) } } else if (parent) { return parent.get(name) } } // Set an existing value. It must already be registered. me.set = function(name, value) { if (name in c) { if (r[name] == BY_VAL) { c[name] = value } else { // by reference (var) setByRef(name, value) } return true } else if (parent) { return parent.set(name, value) } } const getByRef = function(name) { return c[name][r[name]] } const setByRef = function(name, value) { c[name][r[name]] = value } setup() return me }