11import {
2- LoggingDebugSession , OutputEvent , LoadedSourceEvent ,
2+ DebugSession , OutputEvent , LoadedSourceEvent ,
33 InitializedEvent , StoppedEvent , TerminatedEvent , InvalidatedEvent , ContinuedEvent
44} from '@vscode/debugadapter' ;
55import {
66 DebugProtocol
77} from '@vscode/debugprotocol' ;
88import { make_new_runtime , DebugRuntime } from '../mipsy_vscode/pkg/mipsy_vscode' ;
9+ import { ScanBuffer } from './scanBuffer' ;
910const { promises : fs } = require ( "fs" ) ;
1011
1112// const rand = Math.floor(Math.random() * 9000) + 1000;
@@ -21,7 +22,7 @@ class MipsRuntime {
2122 public runningReverse : boolean ;
2223 private isAtExit : boolean = false ;
2324
24- constructor ( readonly source : string , readonly filename : string , readonly path : string , readonly session : MipsSession ) {
25+ constructor ( readonly source : string , readonly filename : string , readonly path : string , readonly session : MipsSession , private readonly scanBuffer : ScanBuffer ) {
2526 this . runtime = make_new_runtime (
2627 source , filename
2728 ) ;
@@ -62,6 +63,17 @@ class MipsRuntime {
6263 this . autoRunning = true ;
6364 }
6465
66+ sendToIOView ( str : string ) {
67+ this . session . sendEvent ( {
68+ event : 'mipsyOutput' ,
69+ body : {
70+ charCodes : [ ...str ] . map ( c => c . charCodeAt ( 0 ) )
71+ } ,
72+ seq : 0 ,
73+ type : 'event'
74+ } ) ;
75+ }
76+
6577 step ( ) : boolean {
6678 if ( this . isAtExit ) {
6779 this . session . sendStdoutLine ( 'exiting...' ) ;
@@ -101,14 +113,7 @@ class MipsRuntime {
101113 this . session . sendStdoutLine ( `syscall ${ printType } : ${ sanitisedContents } ` ) ;
102114 }
103115
104- this . session . sendEvent ( {
105- event : 'mipsyOutput' ,
106- body : {
107- charCodes : [ ...printContents ] . map ( c => c . charCodeAt ( 0 ) )
108- } ,
109- seq : 0 ,
110- type : 'event'
111- } ) ;
116+ this . sendToIOView ( printContents ) ;
112117
113118 return true ;
114119 } else if ( syscallGuard === 'exit' ) {
@@ -119,6 +124,39 @@ class MipsRuntime {
119124 this . runtime . acknowledge_breakpoint ( ) ;
120125 return ! this . autoRunning ; // stop the autorun, but don't stop single stepping
121126 } else if ( syscallGuard . startsWith ( 'read_' ) ) {
127+ if ( ! this . scanBuffer . isExhausted ) {
128+ let result ;
129+ let todoSyscall = false ;
130+
131+ if ( syscallGuard === 'read_int' ) {
132+ result = this . scanBuffer . readInt ( ) ;
133+ } else if ( syscallGuard === 'read_character' ) {
134+ result = this . scanBuffer . readChar ( ) ;
135+ } else {
136+ todoSyscall = true ;
137+ this . session . sendStderrLine (
138+ `Queued input with a ${ syscallGuard } syscall not currently supported`
139+ ) ;
140+ }
141+
142+ if ( result === undefined ) {
143+ if ( this . scanBuffer . isExhausted ) {
144+ this . session . sendStderrLine ( 'All queued input now exhausted' ) ;
145+ } else if ( ! todoSyscall ) {
146+ this . session . sendStderrLine (
147+ `Invalid format encountered in queued input during ${ syscallGuard } syscall: ${ this . scanBuffer . initialContents ( ) } . Queued input removed.`
148+ ) ;
149+ }
150+ this . scanBuffer . clear ( ) ;
151+ } else {
152+ this . session . sendStdoutLine ( `[from queued input] ${ this . provideInput ( result . toString ( ) ) } ` ) ;
153+
154+ if ( ! this . inputNeeded ) {
155+ return true ;
156+ }
157+ }
158+ }
159+
122160 if ( this . inputNeeded ) {
123161 // we've already told the user to enter input, maybe say something different?
124162 this . session . sendStderrLine (
@@ -246,6 +284,8 @@ class MipsRuntime {
246284 this . session . sendEvent ( new StoppedEvent ( 'step' , THREAD_ID ) ) ;
247285 }
248286
287+ this . sendToIOView ( input . trimEnd ( ) + '\n' ) ;
288+
249289 return `syscall ${ sycallType } : ${ input } ` ;
250290 } else if ( result ) {
251291 return result ;
@@ -262,15 +302,20 @@ function numTo32BitHex(value: number) {
262302}
263303
264304// TODO: this is structured incredibly badly
265- class MipsSession extends LoggingDebugSession {
305+ class MipsSession extends DebugSession {
266306 private sourceFilePath : string = '' ;
267307 private source : string = '' ;
268308 private sourceName : string = '<source code>' ;
269309 private initialBreakpoints : number [ ] = [ ] ;
270310 private isVSCode : boolean = false ;
311+ private scanBuffer : ScanBuffer = new ScanBuffer ( ) ;
271312
272313 private runtime : MipsRuntime | undefined ;
273314
315+ constructor ( ) {
316+ super ( ) ;
317+ }
318+
274319 protected initializeRequest ( response : DebugProtocol . InitializeResponse , args : DebugProtocol . InitializeRequestArguments ) : void {
275320 response . body = response . body || { } ;
276321
@@ -356,21 +401,18 @@ class MipsSession extends LoggingDebugSession {
356401 this . sendEvent ( new TerminatedEvent ( ) ) ;
357402 }
358403
359- // this.sendDebugLine(`wow ${this.source}`);
360404 const pathParts = fsPath . split ( / [ \/ \\ ] / ) ;
361405 this . sourceName = pathParts [ pathParts . length - 1 ] ;
362406
363407 try {
364- this . runtime = new MipsRuntime ( this . source , this . sourceName , this . sourceFilePath , this ) ;
408+ this . runtime = new MipsRuntime ( this . source , this . sourceName , this . sourceFilePath , this , this . scanBuffer ) ;
365409 } catch ( e ) {
366410 this . sendError ( 'Error:\n' + e ) ;
367411 this . sendEvent ( new TerminatedEvent ( ) ) ;
368412 }
369413
370414 this . runtime ?. setBreakpoints ( this . initialBreakpoints ) ;
371415
372- // this.sendSource();
373-
374416 this . sendEvent ( new StoppedEvent (
375417 'entry' ,
376418 THREAD_ID
@@ -636,6 +678,26 @@ class MipsSession extends LoggingDebugSession {
636678 return super . sendEvent ( event ) ;
637679 }
638680
681+ protected customRequest ( command : string , response : DebugProtocol . Response , args : any , request ?: DebugProtocol . Request | undefined ) : void {
682+ if ( command === 'queueInput' ) {
683+ if ( this . scanBuffer . isExhausted ) {
684+ this . sendStdoutLine ( '[input queued]' ) ;
685+ } else {
686+ this . sendStdoutLine ( '[previous input queue cleared, and new input queued]' ) ;
687+ }
688+ this . scanBuffer . clear ( ) ;
689+
690+ this . scanBuffer . addToQueue ( args . contents ) ;
691+ this . sendResponse ( response ) ;
692+
693+ if ( this . runtime ?. inputNeeded ) {
694+ this . runtime . step ( ) ;
695+ }
696+
697+ return ;
698+ }
699+ }
700+
639701 protected dispatchRequest ( request : DebugProtocol . Request ) {
640702 // this.sendDebugLine(`request ${JSON.stringify(request)}`);
641703 return super . dispatchRequest ( request ) ;
@@ -647,5 +709,5 @@ class MipsSession extends LoggingDebugSession {
647709 }
648710}
649711
650- const session = new MipsSession ( "out-file.txt" ) ;
712+ const session = new MipsSession ( ) ;
651713session . start ( process . stdin , process . stdout ) ;
0 commit comments