IMPLEMENTATION MODULE AMScan;
(*$ LargeVars:=FALSE *)

FROM SYSTEM IMPORT ASSEMBLE;

(* 26.1.91/bp
 * Semikolon in quotes muß auch gültig sein!
 *)

(*$ EntryExitCode:=FALSE *)
PROCEDURE ScanString(read: ReadProc;
                     VAR st: ARRAY OF CHAR;
                     VAR len: INTEGER;
                     VAR ch: CHAR): BOOLEAN;
CONST
eof = 28;
eol = 10;
space=32;
ht=9;
quote='"';
comment=';';

BEGIN
  ASSEMBLE(
(*
hadSomething	EQUR	D0
ch		EQUR	D1
len		EQUR	D2
read		EQUR	A0
string		EQUR	A1
high		EQUR	D3
inQuotes	EQUR	D4
chAdr		EQUR	A3
lenAdr		EQUR	A6
*)
		LEA	4(A7),A0 (* skip retadr/bp *)
		MOVEM.L	D2-D4/A3/A6,-(A7)
		MOVE.L	(A0)+,A3 (* var ch *)
		MOVE.L	(A0)+,A6 (* var len *)
		MOVE.L	(A0)+,A1 (* var st:adr *)
		MOVE.L	(A0)+,D3 (* var st:high *)
		MOVE.L	(A0)+,A0 (* readProc *)

		MOVEQ	#0,D4
		MOVEQ	#0,D0
		MOVEQ	#0,D2
skipBlanks:
		MOVEM.L	D0/D1/A0/A1,-(A7)
		MOVE.L  A3,-(A7)
		JSR     (A0)
		MOVEM.L	(A7)+,D0/D1/A0/A1
		MOVE.B	(A3),D1
		CMPI.B	#space,D1
		BEQ.S	skipBlanks
		CMPI.B	#ht,D1
		BEQ.S	skipBlanks

while:		CMPI.B	#eof,D1
		BEQ.S	exitWhile
		CMPI.B	#eol,D1
		BEQ.S	exitWhile
		TST.B	D4
		BNE.S	whileLoop
		CMPI.B	#comment,D1 (* ; in quotes ist gültig! *)
		BEQ.S	exitWhile
		CMPI.B	#space,D1
		BEQ.S	exitWhile
		CMPI.B	#ht,D1
		BEQ.S	exitWhile
whileLoop:	CMPI.B	#quote,D1
		BNE.S	notQuote
		NOT.B	D4 (* .b reicht!/bp *)
		BRA.S	endIf
notQuote:	CMP.L	D3,D2
		BGT.S	endIf
		MOVE.B	D1,(A1)+
		ADDQ.L	#1,D2
endIf:
		MOVEM.L	D0/D1/A0/A1,-(A7)
		MOVE.L	A3,-(A7)
		JSR	(A0)
		MOVEM.L	(A7)+,D0/D1/A0/A1
		MOVE.B	(A3),D1
		MOVEQ	#-1,D0
		BRA.S	while
exitWhile:	CMP.L	D3,D2
		BGT.S	return
		CLR.B	(A1)+
return:		MOVE.B	D1,(A3)
		MOVE.W	D2,(A6)
		MOVEM.L	(A7)+,D2-D4/A3/A6
		MOVEA.L	(A7)+,A0
		LEA	20(A7),A7
		JMP	(A0)
  END);
END ScanString;

(* v Das sollte keiner nachmachen, der Guru freut sich! /bp *)
(*$ EntryExitCode:=FALSE *)
BEGIN
 ASSEMBLE(RTS END)
CLOSE
 ASSEMBLE(RTS END)
END AMScan.
