#include "assert.h" #include "commandline/parameters.h" #include "interpreter/contexts.h" #include "memory/virtualmemory.h" #include "object.h" #include "operators/operands.h" #include "resources/categories.h" #include "resources/resources.h" #include "types/attributes.h" #include "types/boolean.h" #include "types/composites/composites.h" #include "types/composites/dictionary.h" #include "types/composites/load.h" #include "types/equality.h" #include "types/numbers/integer.h" #include "types/operator.h" #include "types/typestrings.h" #define localinstances() instances_(string("localinstances")) #define globalinstances() instances_(string("globalinstances")) static inline const object *instances_(const object allocationmode) { const object * const Instances = known(allocationmode, topof(dictionarystack)); if (Instances && Instances->type != dicttype) throw (typecheck); else return Instances; } static void DefineResource_(void) { object * const operand = require(operandstack, anytype, anytype); const object instance = readonly(operand[1]); const object * const instancetype = known(string("InstanceType"), topof(dictionarystack)); if (instancetype && eq(*instancetype, typestring(instance)) == false) throw (typecheck); const object * const Instances = vm.allocationmode ? globalinstances() : localinstances(); if (Instances) { put[dicttype](operand[0], instance, *Instances); if (vm.allocationmode == false) { const object * const Instances = localinstances(); if (Instances) undef(operand[0], *Instances); } } else { throw (undefined); } operand[0] = instance; clearto(operandstack, &operand[1]); } static const object DefineResource = staticoperator("DefineResource", DefineResource_); static void UndefineResource_(void) { object * const operand = require(operandstack, anytype); const object * const Instances = localinstances(); if (Instances) undef(*operand, *Instances); if (vm.allocationmode) { const object * const Instances = globalinstances(); if (Instances) undef(*operand, *Instances); } clearto(operandstack, operand); } static const object UndefineResource = staticoperator("UndefineResource", UndefineResource_); static const object *findresource(const object key) { if (vm.allocationmode == false) { const object * const Instances = localinstances(); if (Instances) { const object * const instance = known(key, *Instances); if (instance) return instance; } } const object * const Instances = globalinstances(); return Instances ? known(key, *Instances) : 0; } static void FindResource_(void) { object * const operand = require(operandstack, anytype); const object * const instance = findresource(*operand); if (instance) *operand = *instance; else throw (undefinedresource); } static const object FindResource = staticoperator("FindResource", FindResource_); static void ResourceStatus_(void) { object * const operand = require(operandstack, anytype); if (findresource(*operand)) { if (spaceon(operandstack) < 2) throw(stackoverflow); *operand = integer(0); push(integer(0), operandstack); push(boolean(true), operandstack); } else { *operand = boolean(false); } } static const object ResourceStatus = staticoperator("ResourceStatus", ResourceStatus_); static void ResourceForAllcontext_(void) { object * const operand = require(executionstack, stringtype, proctype, stringtype, anytype); const object *entry = (object *)(object [pair]){[key] = operand[3]}; const object *instances = vm.allocationmode ? globalinstances() : localinstances(); if (instances == 0 && vm.allocationmode == false) instances = globalinstances(); while (instances) { if (instances->type != dicttype) throw (typecheck); const object Instances = {.type = dicttype, .dict = readvm(instances->dict)}; if (dictaccess(Instances) > readonly) throw (invalidaccess); while (entry = iterate(Instances, entry ? entry[key] : null)) { if (match(operand[0], entry[key])) { if (vm.allocationmode != global(Instances)) { const object * const instances = localinstances(); if (instances && known(entry[key], *instances)) continue; } operand[3] = entry[key]; push(resourceforallcontext, executionstack); push(cvs(entry[value], operand[2]), operandstack); push(operand[1], executionstack); return; } } instances = local(Instances) ? globalinstances() : 0; } clearto(executionstack, &operand[0]); } const object resourceforallcontext = staticoperator("@resourceforall", ResourceForAllcontext_); static void ResourceForAll_(void) { object * const operand = require(operandstack, stringtype, proctype, stringtype); if (spaceon(executionstack) < 4) throw (executionstack->overflow); push(operand[0], executionstack); push(operand[1], executionstack); push(operand[2], executionstack); push(null, executionstack); clearto(operandstack, operand); ResourceForAllcontext_(); } static const object ResourceForAll = staticoperator("ResourceForAll", ResourceForAll_); object defineGeneric(const configure interpreter) { (void)interpreter; return compiled(array(((object []){ cvn(string("Category")), cvn(string("Generic")), cvn(string("DefineResource")), DefineResource, cvn(string("UndefineResource")), UndefineResource, cvn(string("FindResource")), FindResource, cvn(string("ResourceStatus")), ResourceStatus, cvn(string("ResourceForAll")), ResourceForAll }))); }