From 2955730128a669613ac38168630346367d55c918 Mon Sep 17 00:00:00 2001 From: Barry Walsh Date: Wed, 26 Apr 2017 16:57:42 +0100 Subject: [PATCH] REPL - simple fixes and refactoring --- src/os/host-repl.r | 8 +- src/os/host-start.r | 183 ++++++++++++++++++++++++-------------------- 2 files changed, 102 insertions(+), 89 deletions(-) diff --git a/src/os/host-repl.r b/src/os/host-repl.r index 52ff09a26b..24bc01ac16 100644 --- a/src/os/host-repl.r +++ b/src/os/host-repl.r @@ -180,7 +180,7 @@ host-repl: function [ ][ ; REPL is an external object for skinning the behaviour & appearance ; - ; /cycle - updates internal counter and loads repl-skin on first rotation (ie. once) + ; /cycle - updates internal counter and print greeting on first rotation (ie. once) ; repl: system/repl repl/cycle @@ -203,10 +203,10 @@ host-repl: function [ last-failed [ assert [error? :last-result] - print last-result + repl/print-error last-result unless system/state/last-error [ - print "** Note: use WHY for more error information" + repl/print-info "Note: use WHY for more error information" ] system/state/last-error: last-result @@ -279,7 +279,7 @@ host-repl: function [ ; and needs to be closed. Invert the symbol. ; unclosed: switch error/arg1 [ - "}" ["{"] + "}" ["^{"] ")" ["("] "]" ["["] ] diff --git a/src/os/host-start.r b/src/os/host-start.r index 3667e80b6d..0834f568f7 100644 --- a/src/os/host-start.r +++ b/src/os/host-start.r @@ -219,6 +219,7 @@ host-script-pre-load: procedure [ ] ] + host-start: function [ "Loads extras, handles args, security, scripts." return: [integer! function!] @@ -227,7 +228,7 @@ host-start: function [ {Raw command line argument block received by main() as STRING!s} boot-exts [block! blank!] {Extensions (modules) loaded at boot} - host-prot + host-prot repl! o (system/options) ;-- shorthand since options are often read/written ][ @@ -575,100 +576,49 @@ comment [ boot-print boot-help - ; Set up REPL object. This object is used in skinning the REPL + + ; REPL skinning: + ; Instantiate REPL! object into system/repl + ; This object can be updated from %repl-skin.reb (if found in system/user/rebol) ; See /os/host-repl.r where this object is called from - ; %repl-skin.reb if found in system/user/rebol is loaded on REPL start ; - system/repl: make object! [ - counter: 0 - last-result: _ ;-- last evaluated result (sent by HOST-REPL) - - ; Block to allow for multiple skins in the future, max of one for now. - ; - skins: either system/user/rebol [ - reduce [join-of system/user/rebol %repl-skin.reb] - ][ - [] - ] - ; Called on every line of input by HOST-REPL in %os/host-repl.r - ; - cycle: does [ - if zero? ++ counter [load-skin] ;-- only load skin on first cycle - counter - ] + proto-skin: [] + skin-file: if system/user/rebol [join-of system/user/rebol %repl-skin.reb] - load-skin: does [ - if empty? skins [return false] - - print [newline "REPL skinning:" newline] - foreach skin-file skins [ - trap/with [ - print [ - space space - either exists? skin-file [ - do load skin-file - "Loaded skin" - ]["Skin does not exist"] - "-" skin-file - ] - ] func [error] [ - print [ - " Error loading skin" "-" skin-file | - | - error | - | - " Fix error and enter repl/load-skin to reload" - ] - ] + if skin-file [ + boot-print [newline "REPL skinning:" newline] + trap/with [ + ;; load & run skin if found + if loaded-skin?: exists? skin-file [ + new-skin: do load skin-file + + ;; if loaded skin returns REPL! object then use as prototype + if all [ + object? new-skin + true? select new-skin 'repl ;; quacks like a REPL! + ] [proto-skin: new-skin] ] - print-greeting - ] - - ;; APPEARANCE (can be overridden) - - prompt: {>> } - result: {== } - warning: {!! } - print-greeting: _ - print-prompt: proc [] [print/only prompt] - print-result: proc [] [print unspaced [result last-result]] - print-warning: proc [s] [print unspaced [warning reduce s]] - print-gap: proc [] [print-newline] - - ;; BEHAVIOR (can be overridden) - - input-hook: func [ - {Receives line input, parse/transform, send back to repl eval} - s - ][ - s - ] - - dialect-hook: func [ - {Receives code block, parse/transform, send back to repl eval} - s - ][ - s - ] - - shortcuts: make object! [ - q: [quit] - list-shortcuts: [print system/repl/shortcuts] + boot-print [ + space space + either/only loaded-skin? {Loaded skin} {Skin does not exist} + "-" skin-file + unspaced ["(" if/only empty? proto-skin {not } "updated REPL)"] + ] + ] func [error] [ + boot-print [ + { Error loading skin -} skin-file | | + error | | + { Fix error and restart REPL} + ] ] - ;; HELPERS (can be overridden) - - add-shortcut: proc [ - {Add/Change REPL shortcut} - name [any-word!] {shortcut name} - block [block!] {command(s) expanded to} - ][ - extend shortcuts name block - ] + boot-print {} ] + system/repl: make repl! proto-skin + ; Rather than have the host C code look up the REPL function by name, it ; is returned as a function value from calling the start. It's a bit of @@ -678,3 +628,66 @@ comment [ return :host-repl ] + +; Define REPL! object for skinning - stub for elsewhere? +; + +repl!: make object! [ + repl: true + counter: 0 + last-result: _ ;-- last evaluated result (sent by HOST-REPL) + + ; Called on every line of input by HOST-REPL in %os/host-repl.r + ; + cycle: does [ + if zero? ++ counter [print-greeting] ;-- only load skin on first cycle + counter + ] + + ;; APPEARANCE (can be overridden) + + prompt: {>> } + result: {== } + warning: {!! } + error: {** } ;; not used yet + info: to-string #{e29398} ;; info sign! + greeting: _ + print-prompt: proc [] [print/only prompt] + print-result: proc [] [print unspaced [result last-result]] + print-warning: proc [s] [print unspaced [warning reduce s]] + print-error: proc [e] [print e] + print-info: proc [s] [print [info space space reduce s]] + print-greeting: proc [] [boot-print greeting] + print-gap: proc [] [print-newline] + + ;; BEHAVIOR (can be overridden) + + input-hook: func [ + {Receives line input, parse/transform, send back to repl eval} + s + ][ + s + ] + + dialect-hook: func [ + {Receives code block, parse/transform, send back to repl eval} + s + ][ + s + ] + + shortcuts: make object! [ + q: [quit] + list-shortcuts: [print system/repl/shortcuts] + ] + + ;; HELPERS (could be overridden!) + + add-shortcut: proc [ + {Add/Change REPL shortcut} + name [any-word!] {shortcut name} + block [block!] {command(s) expanded to} + ][ + extend shortcuts name block + ] +]