DIRECTORY Basics USING [LowByte, LowHalf], Convert, JaMBasic USING [Object, StringLength, Tag], JaMInternal USING [Frame], JaMOps USING [Error, Install, InstallReason, NameToString, Pop, PopCardinal, PopInteger, PopString, Push, PushBoolean, PushInteger, rangechk, RegisterExplicit, Text], JaMVM USING [AllocString, CopyString, GetChar, GetText, PutChar, PutText]; -- String USING [AppendChar, AppendLongDecimal, AppendLongNumber, StringToLongNumber]; JaMStringImpl: PROGRAM IMPORTS Basics, Convert, JaMOps, JaMVM EXPORTS JaMOps = { OPEN VM:JaMVM, JaMOps, JaMInternal, JaMBasic; lengthLimit: CARDINAL = LAST[StringLength]; true,false,novalue: string Object; Head: PROC[s: string Object, n: CARDINAL] RETURNS[string Object] = INLINE { IF ns.length THEN n _ s.length; s.length _ s.length - n; n _ s.offset + n; s.text _ s.text + n/2; s.offset _ n MOD 2; RETURN[s] }; String: PUBLIC PROC[length: StringLength] RETURNS[string Object] = { s: string Object _ VM.AllocString[length]; s.tag _ L; RETURN[s]; }; SCopy: PUBLIC PROC[string: string Object, expand: CARDINAL _ 0] RETURNS[string Object] = { oldlen: CARDINAL = string.length; newlen: CARDINAL = oldlen + MIN[expand,lengthLimit-oldlen]; new: string Object _ VM.AllocString[newlen]; VM.CopyString[src: string, dst: new]; RETURN[new]; }; SubString: PUBLIC PROC[s: string Object, beg,len: CARDINAL] RETURNS[string Object] = { IF beg>s.length OR len>(s.length-beg) THEN ERROR Error[rangechk]; RETURN[Head[Tail[s,beg],len]]; }; PutString: PUBLIC PROC[from: string Object, beg: CARDINAL, into: string Object] = { IF beg>into.length OR from.length>(into.length-beg) THEN ERROR Error[rangechk]; VM.CopyString[from,Tail[into,beg]]; }; StringCompare: PUBLIC PROC[a,b: string Object] RETURNS[INTEGER] = { FOR i: CARDINAL IN[0..MIN[a.length,b.length]) DO ca: CHARACTER _ VM.GetChar[a,i]; cb: CHARACTER _ VM.GetChar[b,i]; IF ca#cb THEN RETURN[IF ca= s.length) AND StringMatch[s,t,0] THEN { Push[frame.opstk,Tail[t,s.length]]; -- remainder of t following match Push[frame.opstk,Head[t,s.length]]; -- part of t matching s PushBoolean[frame.opstk,TRUE] } ELSE { Push[frame.opstk,t]; -- no match, just push t PushBoolean[frame.opstk,FALSE] }; }; AppendInteger: PROC[s: LONG STRING, i: INT, rdx: CARDINAL _ 10] = { IF rdx=10 THEN [] _ Convert.AppendInt[LOOPHOLE[s], i, 10] ELSE [] _ Convert.AppendCard[LOOPHOLE[s], LOOPHOLE[i], 8]; }; AppendChar: PROC[s: LONG STRING, c: CHAR] = { s[s.length] _ c; s.length _ s.length + 1; }; AppendReal: PROC[s: LONG STRING, r: REAL] = BEGIN [] _ Convert.AppendReal[LOOPHOLE[s], r]; END; ConvertToString: PUBLIC PROC[frame: Frame] = { ob: Object _ Pop[frame.opstk]; string: string Object _ novalue; s: STRING _ [50]; WITH ob:ob SELECT FROM integer => { AppendInteger[s,ob.ivalue]; string _ MakeString[s] }; real => { AppendReal[s,ob.rvalue]; string _ MakeString[s] }; boolean => string _ (IF ob.bvalue THEN true ELSE false); string => string _ ob; name => string _ SCopy[NameToString[ob]]; -- make a copy! ENDCASE; Push[frame.opstk,string]; }; ConvertToRadixString: PUBLIC PROC[frame: Frame] = { rdx: CARDINAL _ PopCardinal[frame.opstk]; ob: Object _ Pop[frame.opstk]; string: string Object _ novalue; s: STRING _ [50]; IF rdx NOT IN[2..36] THEN ERROR Error[rangechk]; WITH ob:ob SELECT FROM integer => { AppendInteger[s,ob.ivalue,rdx]; string _ MakeString[s] }; real => { AppendInteger[s,LOOPHOLE[ob.rvalue],rdx]; string _ MakeString[s] }; ENDCASE; Push[frame.opstk,string]; }; TextIntoString: PROC[from: Text, into: string Object] RETURNS[string Object] = { IF from.length>into.length THEN ERROR Error[rangechk]; into.length _ from.length; VM.PutText[into,from]; RETURN[into] }; StringIntoString: PROC[from,into: string Object] RETURNS[string Object] = { PutString[from,0,into]; into.length _ from.length; RETURN[into] }; ConvertIntoString: PUBLIC PROC[frame: Frame] = { string: string Object _ PopString[frame.opstk]; ob: Object _ Pop[frame.opstk]; result: string Object _ novalue; s: STRING _ [50]; WITH ob:ob SELECT FROM integer => { AppendInteger[s,ob.ivalue]; result _ TextIntoString[s,string] }; real => { AppendReal[s,ob.rvalue]; result _ TextIntoString[s,string] }; boolean => result _ (IF ob.bvalue THEN true ELSE false); string => result _ ob; name => result _ StringIntoString[NameToString[ob],string]; ENDCASE; Push[frame.opstk,result]; }; ConvertIntoRadixString: PUBLIC PROC[frame: Frame] = { string: string Object _ PopString[frame.opstk]; rdx: CARDINAL _ PopCardinal[frame.opstk]; ob: Object _ Pop[frame.opstk]; result: string Object _ novalue; s: STRING _ [50]; IF rdx NOT IN[2..36] THEN ERROR Error[rangechk]; WITH ob:ob SELECT FROM integer => { AppendInteger[s,ob.ivalue,rdx]; result _ TextIntoString[s,string] }; real => { AppendInteger[s,LOOPHOLE[ob.rvalue],rdx]; result _ TextIntoString[s,string] }; ENDCASE; Push[frame.opstk,result]; }; ConvertOctalString: PUBLIC PROC[frame: Frame] = { string: string Object _ PopString[frame.opstk]; s: LONG STRING _ [20]; c: LONG CARDINAL; IF string.length>s.maxlength THEN ERROR Error[rangechk]; VM.GetText[string,s]; c _ Convert.CardFromRope[LOOPHOLE[s], 8 ! Convert.Error => GO TO err]; EXITS err => ERROR Error[rangechk] }; InstallString: PROC[why: InstallReason, frame: Frame] = { SELECT why FROM register => { true _ MakeString[".true"L]; false _ MakeString[".false"L]; novalue _ MakeString["--nostringval--"L]; RegisterExplicit[frame,".string"L,JString]; RegisterExplicit[frame,".copystring"L,JCopyString]; RegisterExplicit[frame,".substring"L,JSubString]; RegisterExplicit[frame,".putstring"L,JPutString]; RegisterExplicit[frame,".sget"L,JSGet]; RegisterExplicit[frame,".sput"L,JSPut]; RegisterExplicit[frame,".search"L,StringSearch]; RegisterExplicit[frame,".asearch"L,StringAnchorSearch]; RegisterExplicit[frame,".cvs"L,ConvertToString]; RegisterExplicit[frame,".cvis"L,ConvertIntoString]; RegisterExplicit[frame,".cvrs"L,ConvertToRadixString]; RegisterExplicit[frame,".cvos"L,ConvertOctalString]; RegisterExplicit[frame,".cvirs"L,ConvertIntoRadixString]; }; ENDCASE; }; Install[InstallString]; }. HJaMStringImpl.mesa Original version John Warnock, January, 1979 Bill Paxton, February 6, 1981 9:31 AM Doug Wyatt, 7-Oct-81 17:17:49 McGregor, September 10, 1982 11:22 am Russ Atkinson, September 26, 1983 1:04 pm Constants Globals The following routines implement a set of string manipulations. Intrinsics Initialization Ê p˜J˜šœ™Jšœ,™,Jšœ&™&Jšœ™Jšœ%™%J™)J˜—šÏk ˜ Jšœœ˜ J˜Jšœ œ˜+Jšœ œ ˜šœ˜ Jšœ™˜™—Jšœœ?˜JJšœ œG˜VJ˜—šœ˜Jšœ˜&Jšœ ˜Jšœœ&˜-J˜—Jšœ ™ J˜Jšœ œœ˜+J˜Jšœ™J˜J˜"J˜Jšœ?™?J˜š Ïnœœœœœ˜KJšœ œœ˜-—š žœœœœœ˜KJšœ œ9˜KJšœ$œœ˜7J˜—šžœœœœ˜DJšœœ˜*Jšœœœ˜J˜J˜—šžœœœ œ˜?Jšœ˜Jšœœ˜!Jšœœ œ˜;Jšœœ˜,Jšœ$œ˜2J˜J˜—šž œœœœ˜;Jšœ˜Jšœœœœ˜AJšœ˜J˜J˜—šž œœœœ˜SJšœœœœ˜OJšœ!˜#J˜J˜—š ž œœœœœ˜Cš œœœœ˜0Jšœ œœ˜ Jšœ œœ˜ Jš œœœœœœ˜.Jšœ˜—Jšœœœ˜#Jš œœœœœ˜1J˜J˜—š ž œœœœœœ˜Nšœœœ˜"Jš œœœœœœ˜:Jšœ˜—Jšœœ˜ J˜J˜—š ž œœœœœ˜LJ˜,Jšœ(˜*Jšœ ˜J˜J˜—šž œœœ'˜>Jšœ˜J˜J˜—šž œœœ˜0Jš œœ œœœ˜+šœœœ˜'Jšœ œœ˜$Jšœ œœ˜Jšœ˜—J˜J˜—Jšœ ™ J˜šžœœœ˜&Jšœœ(˜3J˜J˜J˜—šž œœœ˜*J˜*J˜J˜J˜—šž œœœ˜)Jšœœ˜)Jšœœ˜)J˜*J˜(J˜J˜J˜—šž œœœ˜)J˜*Jšœœ˜)J˜*J˜J˜J˜J˜—šžœœœ˜$Jšœœ˜'J˜*Jšœœ˜Jš œœœœœ˜4Jšœœœ˜!J˜J˜J˜—šžœœœ˜$Jšœœ+˜8Jšœœ˜'J˜*Jšœ œ˜ Jš œœœœœ˜4Jšœœ˜#Jšœ˜J˜J˜—šž œœœ˜+J˜*J˜*š œœœœ˜BšœœÏc˜8J˜Jšœ$Ÿ˜@Jšœ$Ÿ˜;JšœŸ˜9Jšœœ˜Jšœ˜ —Jšœ˜—JšœŸ˜-Jšœœ˜J˜J˜—šžœœœ˜1J˜*J˜*šœœœ˜7Jšœ$Ÿ!˜EJšœ$Ÿ˜;Jšœœ˜—šœ˜JšœŸ˜-Jšœœ˜!—J˜J˜—š ž œœœœœœ ˜Cšœ˜ Jšœœ ˜/Jšœœœ˜:—Jšœ˜J˜—šž œœ œœ˜-Jšœ˜Jšœ˜Jšœ˜J˜—š ž œœœœœ˜1Jšœœ˜(Jšœ˜J˜—šžœœœ˜.J˜J˜ Jšœœ˜šœœ˜J˜BJ˜