(* new module KRML *) MODULE TrOffsets; IMPORT Emit AS EEmit; REVEAL T = BRANDED OBJECT next: T := NIL METHODS emit() END; TYPE OffsetT = T OBJECT offset: CARDINAL OVERRIDES emit := EmitOffset END; TYPE ArrayT = T OBJECT offset: CARDINAL; nbElems: CARDINAL; elSize: CARDINAL; el: T OVERRIDES emit := EmitArray END; CONST (* NOTE. The following two constants must be in synch with those defined in the run-time (module RTHeapKRML) and those defined in the linker (module M3LinkerKRML). *) MapEnd = -1; MapArray = -2; PROCEDURE New( offset: INTEGER ): T = BEGIN RETURN NEW( OffsetT, offset := offset ) END New; PROCEDURE NewArray( offset, nbElems, elSize: CARDINAL; el: T ): T = BEGIN IF nbElems = 0 OR el = NIL THEN RETURN NIL END; RETURN NEW( ArrayT, offset := offset, nbElems := nbElems, elSize := elSize, el := el ) END NewArray; PROCEDURE Append( p, q: T ): T = PROCEDURE Tail( p: T ): T = VAR back: T := NIL; BEGIN WHILE p # NIL DO back := p; p := p.next END; RETURN back END Tail; VAR pt, qt: T; BEGIN pt := Tail( p ); qt := Tail( q ); IF pt = NIL THEN RETURN qt END; IF qt = NIL THEN RETURN pt END; pt.next := q; RETURN qt END Append; PROCEDURE Emit( p: T; inXFile: BOOLEAN ) = BEGIN IF p = NIL THEN RETURN END; IF inXFile THEN EEmit.Op( "b" ) END; EmitList( p ); EEmit.OpI( "@", MapEnd ); IF inXFile THEN EEmit.Op( "\n" ) END END Emit; PROCEDURE EmitList( p: T ) = BEGIN WHILE p # NIL DO p.emit(); p := p.next END END EmitList; PROCEDURE EmitOffset( o: OffsetT ) = BEGIN EEmit.OpI( "@,", o.offset ) END EmitOffset; PROCEDURE EmitArray( a: ArrayT ) = BEGIN EEmit.OpI( " @,", MapArray ); EEmit.OpIII( "@,@,@,", a.offset, a.nbElems, a.elSize ); EmitList( a.el ); EEmit.OpI( "@, ", MapEnd ) END EmitArray; BEGIN END TrOffsets.