mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			257 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| Red [
 | |
|     Title:  "Red console"
 | |
|     Author: ["Nenad Rakocevic" "Kaj de Vos"]
 | |
|     File:   %console.red
 | |
|     Tabs:   4
 | |
|     Rights: "Copyright (C) 2012-2013 Nenad Rakocevic. All rights reserved."
 | |
|     License: {
 | |
|         Distributed under the Boost Software License, Version 1.0.
 | |
|         See https://github.com/dockimbel/Red/blob/master/BSL-License.txt
 | |
|     }
 | |
|     Purpose:    "Just some code for testing Pygments colorizer"
 | |
|     Language:   http://www.red-lang.org/
 | |
| ]
 | |
| 
 | |
| #system-global [
 | |
|     #either OS = 'Windows [
 | |
|         #import [
 | |
|             "kernel32.dll" stdcall [
 | |
|                 AttachConsole:   "AttachConsole" [
 | |
|                     processID       [integer!]
 | |
|                     return:         [integer!]
 | |
|                 ]
 | |
|                 SetConsoleTitle: "SetConsoleTitleA" [
 | |
|                     title           [c-string!]
 | |
|                     return:         [integer!]
 | |
|                 ]
 | |
|                 ReadConsole:     "ReadConsoleA" [
 | |
|                     consoleInput    [integer!]
 | |
|                     buffer          [byte-ptr!]
 | |
|                     charsToRead     [integer!]
 | |
|                     numberOfChars   [int-ptr!]
 | |
|                     inputControl    [int-ptr!]
 | |
|                     return:         [integer!]
 | |
|                 ]
 | |
|             ]
 | |
|         ]
 | |
|         line-buffer-size: 16 * 1024
 | |
|         line-buffer: allocate line-buffer-size
 | |
|     ][
 | |
|         #switch OS [
 | |
|             MacOSX [
 | |
|                 #define ReadLine-library "libreadline.dylib"
 | |
|             ]
 | |
|             #default [
 | |
|                 #define ReadLine-library "libreadline.so.6"
 | |
|                 #define History-library  "libhistory.so.6"
 | |
|             ]
 | |
|         ]
 | |
|         #import [
 | |
|             ReadLine-library cdecl [
 | |
|                 read-line: "readline" [  ; Read a line from the console.
 | |
|                     prompt          [c-string!]
 | |
|                     return:         [c-string!]
 | |
|                 ]
 | |
|                 rl-bind-key: "rl_bind_key" [
 | |
|                     key             [integer!]
 | |
|                     command         [integer!]
 | |
|                     return:         [integer!]
 | |
|                 ]
 | |
|                 rl-insert:   "rl_insert" [
 | |
|                     count           [integer!]
 | |
|                     key             [integer!]
 | |
|                     return:         [integer!]
 | |
|                 ]
 | |
|             ]
 | |
|             #if OS <> 'MacOSX [
 | |
|                 History-library cdecl [
 | |
|                     add-history: "add_history" [  ; Add line to the history.
 | |
|                         line        [c-string!]
 | |
|                     ]
 | |
|                 ]
 | |
|             ]
 | |
|         ]
 | |
| 
 | |
|         rl-insert-wrapper: func [
 | |
|             [cdecl]
 | |
|             count   [integer!]
 | |
|             key     [integer!]
 | |
|             return: [integer!]
 | |
|         ][
 | |
|             rl-insert count key
 | |
|         ]
 | |
|         
 | |
|     ]
 | |
| ]
 | |
| 
 | |
| Windows?: system/platform = 'Windows
 | |
| 
 | |
| read-argument: routine [
 | |
|     /local
 | |
|         args [str-array!]
 | |
|         str  [red-string!]
 | |
| ][
 | |
|     if system/args-count <> 2 [
 | |
|         SET_RETURN(none-value)
 | |
|         exit
 | |
|     ]
 | |
|     args: system/args-list + 1                          ;-- skip binary filename
 | |
|     str: simple-io/read-txt args/item
 | |
|     SET_RETURN(str)
 | |
| ]
 | |
| 
 | |
| init-console: routine [
 | |
|     str [string!]
 | |
|     /local
 | |
|         ret
 | |
| ][
 | |
|     #either OS = 'Windows [
 | |
|         ;ret: AttachConsole -1
 | |
|         ;if zero? ret [print-line "ReadConsole failed!" halt]
 | |
|         
 | |
|         ret: SetConsoleTitle as c-string! string/rs-head str
 | |
|         if zero? ret [print-line "SetConsoleTitle failed!" halt]
 | |
|     ][
 | |
|         rl-bind-key as-integer tab as-integer :rl-insert-wrapper
 | |
|     ]
 | |
| ]
 | |
| 
 | |
| input: routine [
 | |
|     prompt [string!]
 | |
|     /local
 | |
|         len ret str buffer line
 | |
| ][
 | |
|     #either OS = 'Windows [
 | |
|         len: 0
 | |
|         print as c-string! string/rs-head prompt
 | |
|         ret: ReadConsole stdin line-buffer line-buffer-size :len null
 | |
|         if zero? ret [print-line "ReadConsole failed!" halt]
 | |
|         len: len + 1
 | |
|         line-buffer/len: null-byte
 | |
|         str: string/load as c-string! line-buffer len
 | |
|     ][
 | |
|         line: read-line as c-string! string/rs-head prompt
 | |
|         if line = null [halt]  ; EOF
 | |
| 
 | |
|          #if OS <> 'MacOSX [add-history line]
 | |
| 
 | |
|         str: string/load line  1 + length? line
 | |
| ;       free as byte-ptr! line
 | |
|     ]
 | |
|     SET_RETURN(str)
 | |
| ]
 | |
| 
 | |
| count-delimiters: function [
 | |
|     buffer  [string!]
 | |
|     return: [block!]
 | |
| ][
 | |
|     list: copy [0 0]
 | |
|     c: none
 | |
|     
 | |
|     foreach c buffer [
 | |
|         case [
 | |
|             escaped? [
 | |
|                 escaped?: no
 | |
|             ]
 | |
|             in-comment? [
 | |
|                 switch c [
 | |
|                     #"^/" [in-comment?: no]
 | |
|                 ]
 | |
|             ]
 | |
|             'else [
 | |
|                 switch c [
 | |
|                     #"^^" [escaped?: yes]
 | |
|                     #";"  [if zero? list/2 [in-comment?: yes]]
 | |
|                     #"["  [list/1: list/1 + 1]
 | |
|                     #"]"  [list/1: list/1 - 1]
 | |
|                     #"{"  [list/2: list/2 + 1]
 | |
|                     #"}"  [list/2: list/2 - 1]
 | |
|                 ]
 | |
|             ]
 | |
|         ]
 | |
|     ]
 | |
|     list
 | |
| ]
 | |
| 
 | |
| do-console: function [][
 | |
|     buffer: make string! 10000
 | |
|     prompt: red-prompt: "red>> "
 | |
|     mode:  'mono
 | |
|     
 | |
|     switch-mode: [
 | |
|         mode: case [
 | |
|             cnt/1 > 0 ['block]
 | |
|             cnt/2 > 0 ['string]
 | |
|             'else     [
 | |
|                 prompt: red-prompt
 | |
|                 do eval
 | |
|                 'mono
 | |
|             ]
 | |
|         ]
 | |
|         prompt: switch mode [
 | |
|             block  ["[^-"]
 | |
|             string ["{^-"]
 | |
|             mono   [red-prompt]
 | |
|         ]
 | |
|     ]
 | |
|     
 | |
|     eval: [
 | |
|         code: load/all buffer
 | |
|         
 | |
|         unless tail? code [
 | |
|             set/any 'result do code
 | |
|             
 | |
|             unless unset? :result [
 | |
|                 if 67 = length? result: mold/part :result 67 [  ;-- optimized for width = 72
 | |
|                     clear back tail result
 | |
|                     append result "..."
 | |
|                 ]
 | |
|                 print ["==" result]
 | |
|             ]
 | |
|         ]
 | |
|         clear buffer
 | |
|     ]
 | |
| 
 | |
|     while [true][
 | |
|         unless tail? line: input prompt [
 | |
|             append buffer line
 | |
|             cnt: count-delimiters buffer
 | |
| 
 | |
|             either Windows? [
 | |
|                 remove skip tail buffer -2          ;-- clear extra CR (Windows)
 | |
|             ][
 | |
|                 append buffer lf                    ;-- Unix
 | |
|             ]
 | |
|             
 | |
|             switch mode [
 | |
|                 block  [if cnt/1 <= 0 [do switch-mode]]
 | |
|                 string [if cnt/2 <= 0 [do switch-mode]]
 | |
|                 mono   [do either any [cnt/1 > 0 cnt/2 > 0][switch-mode][eval]]
 | |
|             ]
 | |
|         ]
 | |
|     ]
 | |
| ]
 | |
| 
 | |
| q: :quit
 | |
| 
 | |
| if script: read-argument [
 | |
|     script: load script
 | |
|     either any [
 | |
|         script/1 <> 'Red
 | |
|         not block? script/2 
 | |
|     ][
 | |
|         print "*** Error: not a Red program!"
 | |
|     ][
 | |
|         do skip script 2
 | |
|     ]
 | |
|     quit
 | |
| ]
 | |
| 
 | |
| init-console "Red Console"
 | |
| 
 | |
| print {
 | |
| -=== Red Console alpha version ===-
 | |
| (only ASCII input supported)
 | |
| }
 | |
| 
 | |
| do-console |