requires: {#Set}. provides: {#FileModule. #Module}. globals modules: (globals modules as: ExtensibleSequence). "Overrides the interpreter's type for this global." _@lobby enterModule: name "Overrides the interpreter's hook of the same signature." [ globals modules include: name. currentModule: name ]. globals addSlot: #Modules valued: Namespace clone. "TODO: make it a collection?" prototypes addSlot: #Module valued: Cloneable derive. "Modules are a collection of objects and methods, which together provide certain features, and require other modules' features to function." Module addSlot: #requirements valued: Set newEmpty. "Requirements are the set of modules that the given one requires before it can be loaded." Module addSlot: #imports valued: Set newEmpty. "Imports are objects and features referenced by the module's code." Module addSlot: #exports valued: Set newEmpty. "Exports are objects and features provided by the module's code." Module addSlot: #objects valued: Set newEmpty. "These are the non-method objects that the module defines and installs." Module addSlot: #methods valued: Set newEmpty. "These are the closures that the module defines and installs, whether named or dispatched or anonymous." m@(Module traits) initialize "Reset all of the module's attributes." [ m requirements: m requirements newEmpty. m imports: m imports newEmpty. m exports: m exports newEmpty. m objects: m objects newEmpty. m methods: m methods newEmpty. m ]. m@(Module traits) newEmpty [ m clone initialize ]. m@(Module traits) newForFileNamed: filename [ FileModule newForFileNamed: filename ]. m@(Module traits) copy [| newM | newM: m clone. newM requirements: m requirements copy. newM imports: m imports copy. newM exports: m exports copy. newM objects: m objects copy. newM methods: m methods copy. newM ]. m@(Module traits) newBasedOn: moduleSet [| newM | newM: m clone initialize. newM requirements: (moduleSet select: [| :each | each is: Module]). newM ]. m@(Module traits) provide: obj [ "TODO: include some check here to avoid arbitrary provision." m exports include: obj ]. m@(Module traits) provides: obj [ "TODO: do modules automatically export their imports?" m exports includes: obj ]. m@(Module traits) import: obj from: prereq [ (prereq provides: obj) ifTrue: [m requirements include: prereq. m imports include: obj]. m ]. m@(Module traits) importAll: c from: prereq [ c do: [| :each | (prereq provides: each) ifFalse: [^ (prereq error: prereq name ; ' does not provide ' ; each print)]]. m requirements include: prereq. c do: [| :each | m imports include: each]. m ]. prototypes addSlot: #FileModule valued: Module derive. "FileModules are Modules which are drastically simplified for the purposes of bootstrapping. Requirements and provisions are symbols, and other features are ignored." FileModule addSlot: #filename valued: ''. m@(FileModule traits) newForFileNamed: filename [| newM | newM: m newEmpty. newM filename: filename. newM ]. m@(FileModule traits) readDefinitions "Reads in a file, building the module's collections while evaluating the contents." "TODO: implement it!" [| input | input: (FileStream newForInputNamed: m filename). input close. m ]. m@(FileModule traits) metaInfoFilename [| basename | basename: (m filename sliceFrom: 0 to: (m filename indexOfSubSeq: '.slate')). basename ; '.module' ]. m@(FileModule traits) writeOutInfo "Writes out a source definition of the Module object described by the given filename." "TODO: implement it!" [| output | output: (FileStream newForOuputNamed: m metaInfoFilename). output ; '[| m |\n'. output ; 'm: Module newForFileNamed: ' ; m filename ; '.\n'. output ; 'm imports: '. m imports printOn: output. output ; '.\n'. output ; 'm exports: '. m exports printOn: output. output ; '.\n'. output ; 'modules include: m.\n'. output ; 'm] value.\n'. output close. m ]. "SourceWriter print: ([| M | M: Module newForFileNamed: (m filename) `unquote. M imports: (m imports) `unquote. M exports: (m exports) `unquote. modules include: M. M] value. ) `quote on: output." m@(FileModule traits) readInInfo "Reads from a source definition of the Module object described by the given filename." "TODO: implement it!" [| input | input: (FileStream newForInputNamed: m metaInfoFilename). input close. m ].