VM addPrototype: #Pidgin derivedFrom: {Cloneable}. VM Pidgin addSlot: #generator valued: C SimpleGenerator newEmpty. VM Pidgin addSlot: #modules valued: ExtensibleArray newEmpty. c@(VM Pidgin traits) newEmpty [| newC | newC: c clone. newC generator: c generator newEmpty. newC modules: c modules newEmpty. newC ]. c@(VM Pidgin traits) processFile: filename "Reads and translates source from the Slate file." [| parser | File withOpenNamed: filename do: [| :in | parser: (Syntax Parser newOn: in reader). inform: 'Reading \'' ; filename ; '\''. [parser isAtEnd] whileFalse: [| syntax | C currentModule ifNil: [parser typesNamespace: Types C. parser currentScope: Syntax Lobby] ifNotNil: [parser typesNamespace: C currentModule namespace. parser currentScope: (Syntax Namespace for: C currentModule namespace)]. inform: 'parsing ' ; parser lexer lineNumber print. syntax: parser next. syntax: syntax macroExpand. inform: 'processing'. c generator process: syntax]]. ]. VM addSlot: #primitives valued: ExtensibleArray newEmpty. prim@(Syntax MethodDefinition traits) pidginPrimitive [| def index cName primsArray args | C currentModule ifNil: [error: 'Pidgin primitives must be defined in a C module.']. (C currentModule namespace hasSlotNamed: #primitives) ifFalse: [C currentModule addGlobalNamed: #primitives valued: ({} as: C Syntax ArrayLiteral) type: (Types C Array of: (Types C FunctionPointer from: {C currentModule namespace Interpreter pointer. C currentModule namespace ObjectPointer pointer. Types C UnsignedLongInt. C currentModule namespace OopArray pointer} to: {Types C Void}))]. primsArray: C currentModule namespace primitives. index: primsArray init elements size. VM primitives addLast: index -> prim. cName: ('_primitive' ; index print) intern. primsArray init elements: primsArray init elements ; {C Syntax FunctionRef of: cName type: primsArray type elementType}. def: Syntax MethodDefinition newEmpty. def parentScope: prim parentScope. def selector: cName. def roles: { Syntax UnaryMessage sending: #pointer to: {Syntax UnaryMessage sending: #Interpreter to: {Syntax ImplicitArgument}}. Syntax Literal for: NoRole. Syntax Literal for: NoRole }. (def addInputVariableNamed: #interpreter) type: C currentModule namespace Interpreter pointer. args: (def addInputVariableNamed: #arguments). args type: C currentModule namespace ObjectPointer pointer. (def addInputVariableNamed: #argumentsSize) type: Types C UnsignedLongInt. (def addInputVariableNamed: #optionals) type: C currentModule namespace OopArray pointer. def addVariablesFrom: prim. def statements: (prim inputVariables collectWithIndex: [| :var :index | var type: C currentModule namespace ObjectPointer. Syntax StoreVariable of: (Syntax KeywordMessage sending: #at: to: {Syntax LoadVariable from: args. Syntax Literal for: index}) into: var ]) ; prim statements. def linkVariables ]. c@(VM Pidgin traits) generate [ inform: 'generating modules'. C modules do: [| :module | inform: 'generating module'. c generator generate: module] ]. c@(VM Pidgin traits) emitOn: filename "Writes a C and header output file pair from the accumulated C Modules and state of the Pidgin generator." [ File withOpenNamed: filename ; '.h' do: [| :headerfile hdr | hdr: headerfile writer. hdr position: 0. File withOpenNamed: filename ; '.c' do: [| :srcfile src | src: srcfile writer. src position: 0. C modules do: [| :module | inform: 'emitting header to file'. c generator emitHeader: module on: hdr. inform: 'emitting module to file'. c generator emit: module on: src]]]. ]. "The names of the sources used for building the vm, in necessary load-order." VM Pidgin addImmutableSlot: #sourceFilenames valued: {'bootstrap/mobius/vm/layout.slate'. 'bootstrap/mobius/vm/memory.slate'. 'bootstrap/mobius/vm/mark-compact.slate'. 'bootstrap/mobius/vm/object.slate'. 'bootstrap/mobius/vm/map.slate'. 'bootstrap/mobius/vm/dispatch.slate'. 'bootstrap/mobius/vm/vm.slate'. 'bootstrap/mobius/vm/prims.slate'. 'bootstrap/mobius/vm/file.slate' }. c@VM generateVM: vmName [| compiler | VM primitives clear. C modules clear. C currentModule: Nil. compiler: c Pidgin newEmpty. c Pidgin sourceFilenames do: [| :each | compiler processFile: each]. compiler generate. compiler emitOn: vmName. ]. VM addPrototype: #ImageBuilder derivedFrom: {Cloneable}. VM ImageBuilder addSlot: #parser valued: Syntax Parser copy. VM Pidgin addImmutableSlot: #bootstrapFilenames valued: {'bootstrap/root.slate'. 'bootstrap/nil.slate'. 'bootstrap/boolean.slate'. 'bootstrap/namespace.slate'. 'bootstrap/derivable.slate'. 'bootstrap/numeric.slate'. 'bootstrap/method.slate'. 'bootstrap/integer.slate'. 'bootstrap/collection.slate'. 'bootstrap/extensible.slate'. 'bootstrap/mixin.slate'. 'bootstrap/numericMixin.slate'. 'bootstrap/set.slate'. 'bootstrap/mapping.slate'. 'bootstrap/dictionary.slate'. 'bootstrap/sequence.slate'. 'bootstrap/arrayed.slate'. 'bootstrap/string.slate'. 'bootstrap/symbol.slate'. 'bootstrap/range.slate'. 'bootstrap/ordered.slate'. 'bootstrap/linkedlist.slate'. 'bootstrap/cord.slate'. 'bootstrap/sorted.slate'. 'bootstrap/bag.slate'. 'bootstrap/tuple.slate'. 'bootstrap/condition.slate'. 'bootstrap/condition-epilogue.slate'. 'bootstrap/stream.slate'. 'bootstrap/iterator.slate'. 'bootstrap/external.slate'. 'bootstrap/debugger.slate'. 'bootstrap/file.slate'. 'bootstrap/print.slate'. 'bootstrap/mobius/types.slate'. 'bootstrap/mobius/syntax/syntax.slate'. 'bootstrap/mobius/syntax/token.slate'. 'bootstrap/mobius/syntax/lexer.slate'. 'bootstrap/mobius/syntax/parser.slate'. 'bootstrap/mobius/syntax/macro.slate'. 'bootstrap/mobius/syntax/quote.slate'. 'bootstrap/mobius/syntax/inference.slate'. 'bootstrap/mobius/syntax/writer.slate'. 'bootstrap/mobius/syntax/mode.slate'. 'bootstrap/mobius/vm/bytecode.slate'. 'bootstrap/mobius/vm/bytecompiler.slate'. 'bootstrap/mobius/vm/interpreter.slate'. 'bootstrap/mobius/repl.slate' }. s@(String traits) parseFile [| file parser | file: (File ReadStream newOn: s). parser: (Syntax Parser newOn: file). parser upToEnd as: Array ]. c@VM buildImage: imageName &littleEndian: littleEndian [| builder imageFile bootBlock | builder: VM Bootstrap Generator newEmpty. littleEndian ifNotNil: [builder littleEndian: littleEndian]. imageFile: (File WriteStream newOn: imageName). imageFile open. bootBlock: Syntax Block newEmpty. c Pidgin bootstrapFilenames do: [| :each | inform: 'Parsing ' ; each ; ''. bootBlock statements: bootBlock statements ; each parseFile ]. inform: 'Building image.'. builder generateImageBooting: bootBlock compile withPrims: VM primitives. builder emitOn: imageFile. imageFile close. builder ].