DIRECTORY
Environment USING [Byte],
Format USING [Number, SubString, StringProc],
MopOps USING [ESCAlphaNames, FopNames, MopNames, SDDefsNames],
Runtime USING [GetTableBase, IsBound],
String
USING [
AppendOctal, AppendSubString, SubString, SubStringDescriptor, UpperCase];
MopImpl:
PROGRAM
IMPORTS Format, MopOps, Runtime, String
EXPORTS MopOps =
BEGIN
CompStrDesc: TYPE = RECORD [offset, length: CARDINAL];
OpRecord:
TYPE =
RECORD [
stringOffset: OpPtr RELATIVE POINTER TO StringBody,
opcode: ARRAY Environment.Byte OF CompStrDesc];
OpPtr: TYPE = LONG BASE POINTER TO OpRecord;
mopdata: OpPtr ← NIL;
fopdata: OpPtr ← NIL;
escdata: OpPtr ← NIL;
sddata: OpPtr ← NIL;
Mopcodes
PutMopcode:
PUBLIC
PROC [proc: Format.StringProc, n:
CARDINAL] = {
IF mopdata = NIL THEN mopdata ← GetBase[MopOps.MopNames];
PutOpcode[proc, n, mopdata]};
AppendMopcodeName:
PUBLIC
PROC [s:
LONG
STRING, n:
CARDINAL] = {
IF mopdata = NIL THEN mopdata ← GetBase[MopOps.MopNames];
AppendOpcodeName[s, n, mopdata]};
MopcodeValue:
PUBLIC
PROC [s:
LONG
STRING]
RETURNS [
INTEGER] = {
IF mopdata = NIL THEN mopdata ← GetBase[MopOps.MopNames];
RETURN[SearchForOp[s, mopdata]]};
Fopcodes
PutFopcode:
PUBLIC
PROC [proc: Format.StringProc, n:
CARDINAL] = {
IF fopdata = NIL THEN fopdata ← GetBase[MopOps.FopNames];
PutOpcode[proc, n, fopdata]};
AppendFopcodeName:
PUBLIC
PROC [s:
LONG
STRING, n:
CARDINAL] = {
IF fopdata = NIL THEN fopdata ← GetBase[MopOps.FopNames];
AppendOpcodeName[s, n, fopdata]};
FopcodeValue:
PUBLIC
PROC [s:
LONG
STRING]
RETURNS [
INTEGER] = {
IF fopdata = NIL THEN fopdata ← GetBase[MopOps.FopNames];
RETURN[SearchForOp[s, fopdata]]};
ESCAlpha names
PutEscAlpha:
PUBLIC
PROC [proc: Format.StringProc, n:
CARDINAL] = {
IF escdata = NIL THEN escdata ← GetBase[MopOps.ESCAlphaNames];
PutOpcode[proc, n, escdata]};
AppendEscAlpha:
PUBLIC
PROC [s:
LONG
STRING, n:
CARDINAL] = {
IF escdata = NIL THEN escdata ← GetBase[MopOps.ESCAlphaNames];
AppendOpcodeName[s, n, escdata]};
EscAlphaValue:
PUBLIC
PROC [s:
LONG
STRING]
RETURNS [
INTEGER] = {
IF escdata = NIL THEN escdata ← GetBase[MopOps.ESCAlphaNames];
RETURN[SearchForOp[s, escdata]]};
SDDefs names
PutSdName:
PUBLIC
PROC [proc: Format.StringProc, n:
CARDINAL] = {
IF sddata = NIL THEN sddata ← GetBase[MopOps.SDDefsNames];
PutOpcode[proc, n, sddata]};
AppendSdName:
PUBLIC
PROC [s:
LONG
STRING, n:
CARDINAL] = {
IF sddata = NIL THEN sddata ← GetBase[MopOps.SDDefsNames];
AppendOpcodeName[s, n, sddata]};
SdNameValue:
PUBLIC
PROC [s:
LONG
STRING]
RETURNS [
INTEGER] = {
IF sddata = NIL THEN sddata ← GetBase[MopOps.SDDefsNames];
RETURN[SearchForOp[s, sddata]]};
Utilities
GetBase:
PROC [p:
PROGRAM]
RETURNS [
LONG
POINTER] = {
IF Runtime.IsBound[p] THEN RETURN [Runtime.GetTableBase[p]]
ELSE RETURN[NIL]};
PutOpcode:
PROC [proc: Format.StringProc, n:
CARDINAL, lp: OpPtr] = {
ss: String.SubStringDescriptor;
SetupOp[lp, n, @ss];
IF ss.length = 0 THEN Format.Number[proc, n, [8,TRUE,TRUE,3]]
ELSE Format.SubString[proc, @ss]};
AppendOpcodeName:
PROC [s:
LONG
STRING, n:
CARDINAL, lp: OpPtr] = {
ss: String.SubStringDescriptor;
SetupOp[lp, n, @ss];
IF ss.length = 0 THEN String.AppendOctal[s, n]
ELSE String.AppendSubString[s, @ss]};
SetupOp:
PROC [lp: OpPtr, n:
CARDINAL, ss: String.SubString] = {
IF lp = NIL THEN ss^ ← [base: NIL, length: 0, offset: 0]
ELSE {
ss.base ← @lp[lp.stringOffset];
[offset: ss.offset, length: ss.length] ← lp.opcode[n]}};
SearchForOp:
PROC [s:
LONG
STRING, lp: OpPtr]
RETURNS [
INTEGER] = {
desc: String.SubStringDescriptor;
mopdesc: String.SubStringDescriptor;
IF lp = NIL THEN RETURN[-1];
desc ← [base: s, offset: 0, length: s.length];
mopdesc.base ← @lp[lp.stringOffset];
FOR byte: Environment.Byte
IN Environment.Byte
DO
[offset: mopdesc.offset, length: mopdesc.length] ← lp.opcode[byte];
IF desc.length = mopdesc.length
AND
SameChars[@desc, @mopdesc] THEN RETURN[byte];
ENDLOOP;
RETURN[-1]};
SameChars:
PROC [a,b:
POINTER
TO String.SubStringDescriptor]
RETURNS [BOOLEAN] =
BEGIN
FOR i:
CARDINAL
IN [0..a.length)
DO
IF String.UpperCase[a.base[a.offset+i]] #
String.UpperCase[b.base[b.offset+i]] THEN RETURN [FALSE];
ENDLOOP;
RETURN [TRUE];
END;
END.