prototypes addPrototype: #REPL derivedFrom: {Cloneable}. REPL addSlot: #parser valued: Syntax Parser clone. REPL addSlot: #printer valued: String writer. REPL addSlot: #namespace valued: lobby. REPL addSlot: #lineCount valued: 0. REPL addSlot: #basePrompt valued: '> '. repl@(REPL traits) prompt [ 'Slate ' ; repl lineCount print ; repl basePrompt ]. repl@(REPL traits) on: resource "Re-target the REPL to the specified resource." [ repl parser: (repl parser newOn: resource reader). repl printer: resource writer. repl ]. _@lobby interpretHook: block "The default set of restarts for any errors in a block of code." [ block handlingCases: { (Interpreter InspectFrame in: bootstrapInterpreter) -> [| :_ |]. Abort -> [| :_ | ^ Nil]. Quit -> [| :_ |] } ]. repl@(REPL traits) enter [ [repl lineCount: repl lineCount + 1. repl printer ; repl prompt. repl printer flush. (repl namespace interpretHook: [repl parser next evaluateIn: repl namespace]) printOn: repl printer. repl printer newLine. repl printer flush] loop ]. _@lobby inform: message [ Console writer ; message ; '\n'. ]. _@lobby load: fileName [| aParser | inform: 'Loading \'' ; fileName ; '\'.'. File withOpenNamed: fileName do: [| :input | aParser: (Syntax Parser newOn: input reader). [aParser isAtEnd] whileFalse: [aParser next evaluate]]. ]. repl@(REPL traits) completionsFor: word "TODO: Consult the Symbol table or recent literal frames for names with the given string as a prefix. Collect the results and return them." [| result | result: {} writer. globals Symbols keysDo: [| :key | (word isPrefixOf: key) ifTrue: [result nextPut: key]]. result contents ]. repl@(REPL traits) enterBoot [ [repl lineCount: repl lineCount + 1. repl printer ; repl prompt. repl printer flush. (Syntax Block newFor: repl parser next) compileAndRun printOn: repl printer. repl printer newLine. repl printer flush] loop ]. _@lobby repl "Enter a new REPL instance." [| repl | repl: (REPL clone on: Console). repl enter. ]. inform: 'Hi, there!'. lobby repl