; ; interp.s ; ; Main entry point for the interpreter ; ; © 1995 Straylight ; ;----- Standard Header ------------------------------------------------------ GET libs:header GET libs:swis GET libs:stream ;----- External dependencies ------------------------------------------------ GET sh.anchor GET sh.ctrl GET sh.errNum GET sh.error GET sh.express GET sh.getToken GET sh.sail GET sh.tokens GET sh.upcalls ;----- Main code ------------------------------------------------------------ AREA |Sapphire$$Code|,CODE,READONLY ; --- interp_start --- ; ; On entry: R12 == pointer to our anchor block ; ; On exit: R7-R9 == next token ; ; Use: Prepares for execution, and even does some too. EXPORT interp_start interp_start ROUT LDR R10,sail_tokAnchor ;Load the anchor MOV R14,#1 ;The current line number STR R14,sail_line ;Store it MOV R9,#-1 ;Prepare for the first line BL getToken ;Get the first token ready SWI OS_ReadMonotonicTime ;Read the current time STR R0,sail_timeSoFar ;Remember this time B interp_exec ;Do some execution LTORG ; --- interp_resume --- ; ; On entry: R12 == script anchor ; ; On exit: -- ; ; Use: Resumes the script from where it left off. EXPORT interp_resume ; --- interp_exec --- ; ; On entry: R7-R9 == token to deal with ; R11 == offset in file to execute from ; R12 == pointer to the anchor block ; ; On exit: R0 == type code (eg. 0 == we are still executing ; R7-R9 == next token to deal with ; ; Use: Executes some of the file. EXPORT interp_exec interp_exec ROUT LDR R1,sail_preempt ;Load the pre-emption time CMP R1,#-1 ;Do we need to return? BEQ %10interp_exec ;No -- jump onwards then SWI OS_ReadMonotonicTime ;Read the current time LDR R14,sail_timeSoFar ;Load the time we started SUB R0,R0,R14 ;Thie we have been executing CMP R0,R1 ;Time up yet? BCC %10interp_exec ;No -- keep on going then ; --- Return control for a little while then --- 00interp_exec B sail_wait ;Yes -- wait some then interp_resume SWI OS_ReadMonotonicTime ;Read the current time STR R0,sail_timeSoFar ;Remember this time 10interp_exec CMP R7,#tClass_instr ;Is this an instruction? BNE %50interp_exec ;No -- could be other things ; --- We have an instruction --- MOV R0,R8 ;Look after index BL getToken ;Get the next tokem ADD PC,PC,R0,LSL #2 ;Branch to the correct code DCB "Jive" ; --- The main dispatch table --- B ctrl_bput B ctrl_case B ctrl_close B ctrl_call ;CALL B ctrl_data B ctrl_def B ctrl_dim B ctrl_end B ctrl_endproc B ctrl_endwhile B interp_next ;ENDIF B interp_next ;ENDCASE B ctrl_else B interp_notImpl ;B ctrl_error B ctrl_for B ctrl_goto B ctrl_gosub B ctrl_if B ctrl_let B ctrl_local B ctrl_next B ctrl_oscli ;OSCLI B ctrl_otherwise B ctrl_proc B ctrl_return B ctrl_repeat B ctrl_read B ctrl_restore B ctrl_swap B ctrl_sys B ctrl_until B ctrl_while B ctrl_when ; --- Handle pseudo varaible and the like --- 50interp_exec SUBS R4,R9,#'_' ;Is it an underscore? SUBNES R4,R9,#'!' SUBNES R4,R9,#'?' SUBNES R4,R9,#'$' SUBNE R4,R9,#'A' ;Or a capital letter? CMP R4,#26 SUBCS R4,R9,#'a' ;Or a lowercase letter? CMPCS R4,#26 BCC ctrl_let ;If so, assume assignment CMP R9,#tok_time ;Is this a TIME pseudovar? BLEQ getToken ;Yes -- done with this token BEQ ctrl_timeEq ;Yes -- assign that then CMP R7,#tClass_streamOp ;Is it a streamOp? BNE %60interp_exec ;No -- jump ahead MOV R0,R9 ;Remember the tokoen BL getToken ;Get another token CMP R9,#'#' ;Do we have a hash next? MOVNE R0,#err_expHash ;No -- complain then BNE error_report ;And report an error BL getToken ;Get the next token CMP R0,#tok_ptr ;Setting of pointer? BEQ ctrl_ptr ;Yes -- do that then CMP R0,#tok_ext ;Setting of extent? BEQ ctrl_ext ;Yes -- do that BNE interp_next ;Probably emtpy statement 60interp_exec CMP R7,#tClass_multArg ;A multiple argument thing? BNE %70interp_exec ;No -- jump ahead ; --- Deal with a multiple argument command --- CMP R9,#tok_leftS ;Is it LEFT$? BLEQ getToken ;Yes -- get a token BEQ ctrl_leftS ;Yes -- deal with it CMP R9,#tok_midS ;Is it MID$? BLEQ getToken ;Yes -- get a token BEQ ctrl_midS ;Yes -- deal with it CMP R9,#tok_rightS ;Is it RIGHT$? BLEQ getToken ;Yes -- get a token BEQ ctrl_rightS ;Yes -- deal with it BNE interp_next ;Probably emtpy statement 70interp_exec CMP R9,#'=' ;Is it a return-from-fn? BLEQ getToken ;Yes -- gobble it then BEQ ctrl_equals ;Yes -- return then CMP R9,#'*' ;Is this a star command? BNE interp_next ;Probably emtpy statement ; --- We have a star command --- ; ; We copy the command into a buffer, until we reach ; a terminating character. ADR R0,sail_misc ;Point to the destination 00 BL getToken ;Get a token CMP R9,#10 ;Is this the end of the line? CMPNE R9,#&FF ;Or the end of the file STRNEB R9,[R0],#1 ;No -- store the byte BNE %b00 ;And keep on going ; --- We have the string in the buffer --- MOV R14,#0 ;We had better terminate it STRB R14,[R0],#1 ;By store a NULL char ADR R0,sail_misc ;Point to the command SWI OS_CLI ;Perform the command B interp_next ;Just keep on goin' then LTORG ; --- interp_notImpl --- EXPORT interp_notImpl interp_notImpl MOV R0,#err_lazy B error_report ; --- interp_next --- ; ; On entry: R7-R9 == token to deal with ; R11 == offset in file to execute from ; R12 == pointer to the anchor block ; ; On exit: R0 == type code (eg. 0 == we are still executing) ; R7-R9 == next token to deal with ; ; Use: Checks the next instruction and acts approriately. EXPORT interp_next interp_next ROUT CMP R9,#10 ;Is this newline? LDR R14,sail_flags ;Load the flags word ORREQ R14,R14,#tscFlag_nl ;Newline just arrived BICNE R14,R14,#tscFlag_nl ;Or maybe not STR R14,sail_flags ;Store the new flags back CMPNE R9,#':' ;Is this a ':'? BLEQ getToken ;Either -- get a token BEQ interp_exec ;...and keep on looping CMP R9,#tok_else ;Is this an ELSE? BLEQ getToken ;Yes -- read a token BEQ ctrl_else ;...and branch to else ctrl SUBS R0,R9,#&FF ;Is this the end? BEQ sail_return ;Yes -- just end then MOV R0,#err_syntax ;This is a synatx error B error_report ;So report it LTORG ;----- That's all, folks ---------------------------------------------------- END