MODULE Library; IMPORT AGRS,Names,Texts,TextFrames; CONST (* Kodovi gresaka koji su sadrzani u tipu podataka Error. *) NotLogicalType*= 0; NotNumberType*= 1; NotCharacterType*= 2; NotStringType*= 3; NotTextType*= 4; NotFound*= 5; SyntaxError*= 6; CharSetLength= 256 DIV (MAX(SET)+1); TYPE Term= AGRS.Term; ErrorType= INTEGER; NamesType= POINTER TO RECORD(AGRS.ClosedClassDesc) END; Number*= POINTER TO RECORD(AGRS.AtomicDesc) value*: INTEGER; END; String*= POINTER TO RECORD(AGRS.AtomicDesc) value-: Names.CharPtr; END; Text*= POINTER TO RECORD(AGRS.AtomicDesc) base-: Texts.Text; startOffset-,endOffset-: LONGINT; END; Character*= POINTER TO RECORD(AGRS.AtomicDesc) value-: CHAR; END; CharSet*= POINTER TO RECORD( AGRS.AtomicDesc) value-: ARRAY CharSetLength OF SET; END; Error*= POINTER TO RECORD(AGRS.AtomicDesc) value-: ErrorType; END; BinOp= POINTER TO RECORD(AGRS.TermDesc) END; VAR TrueDef: Term; disTerm: AGRS.Disjunction; NamesTerm: NamesType; atomicName,numberName*,errorName*: AGRS.Name; charName*,stringName*,textName*,charSetName*: AGRS.Name; ifName,orName,andName,notName,testName,yesName,noName: AGRS.Name; addName*,subName*,mulName*,divName,modName: AGRS.Name; argName1*,argName2*: AGRS.Name; equalName,lessName,greaterName,lessEqName,grEqName: AGRS.Name; trueName*,disName,unifyName: AGRS.Name; abortName*,findName,nameName: AGRS.Name; carName,cdrName,consName,nilName: AGRS.Name; namesName: AGRS.Name; PROCEDURE NewNumber*(v: INTEGER): Number; VAR result: Number; BEGIN NEW(result); result.Init(numberName); result.value:= v; AGRS.eldestAsked:= AGRS.Fixed; RETURN result; END NewNumber; PROCEDURE NewString*(v: Names.CharPtr): String; VAR result: String; BEGIN NEW(result); result.Init(stringName); result.value:= v; AGRS.eldestAsked:= AGRS.Fixed; RETURN result; END NewString; PROCEDURE NewChar*(v: CHAR): Character; VAR result: Character; BEGIN NEW(result); result.Init(charName); result.value:= v; AGRS.eldestAsked:= AGRS.Fixed; RETURN result; END NewChar; PROCEDURE NewCharSet*(): CharSet; VAR result: CharSet; i: INTEGER; BEGIN NEW(result); result.Init(charSetName); FOR i:= 0 TO CharSetLength-1 DO result.value[i]:= {}; END; AGRS.eldestAsked:= AGRS.Fixed; RETURN result; END NewCharSet; PROCEDURE (t: String) Length*(): LONGINT; VAR i: LONGINT; str: Names.CharPtr; BEGIN i:= 0; str:= t.value; WHILE str[i]#0X DO INC(i); END; RETURN i END Length; PROCEDURE (t: CharSet) Include*(ch: CHAR); BEGIN INCL(t.value[ORD(ch) DIV (MAX(SET)+1)],ORD(ch) MOD (MAX(SET)+1)); END Include; PROCEDURE (t: CharSet) Complement*(); VAR i: INTEGER; BEGIN FOR i:= 0 TO CharSetLength-1 DO t.value[i]:= -t.value[i]; END; END Complement; PROCEDURE NewError*(v: ErrorType): Error; VAR result: Error; BEGIN NEW(result); result.Init(errorName); AGRS.eldestAsked:= AGRS.Fixed; result.value:= v; RETURN result END NewError; PROCEDURE SubText*(txt: Texts.Text; startPos,endPos: LONGINT): Text; VAR newTerm: Text; BEGIN NEW(newTerm); newTerm.Init(textName); newTerm.base:= txt; newTerm.startOffset:= startPos; newTerm.endOffset:= endPos; RETURN newTerm END SubText; PROCEDURE (t: Text) AppendText*(appendage: Text); VAR temp: Texts.Buffer; newText: Texts.Text; BEGIN IF (t.base=appendage.base) & (t.endOffset=appendage.startOffset) THEN t.endOffset:= appendage.endOffset; ELSE newText:= TextFrames.Text(""); NEW(temp); Texts.OpenBuf(temp); Texts.Save(t.base,t.startOffset,t.endOffset,temp); Texts.Save(appendage.base,appendage.startOffset,appendage.endOffset,temp); Texts.Append(newText,temp); t.base:= newText; t.startOffset:= 0; t.endOffset:= newText.len; END; END AppendText; PROCEDURE (t: Text) AppendBuffer*(appendage: Texts.Buffer); VAR newText: Texts.Text; BEGIN IF t.endOffset=t.base.len THEN Texts.Append(t.base,appendage); t.endOffset:= t.base.len; ELSE newText:= TextFrames.Text(""); Texts.Append(newText,appendage); t.base:= newText; t.startOffset:= 0; t.endOffset:= newText.len; END; END AppendBuffer; PROCEDURE (t: NamesType) Evaluate*(query: Term): Term; BEGIN RETURN NewString(Names.NameSpelling(query.indirection)) END Evaluate; PROCEDURE pType; VAR newTerm: AGRS.OpenTree; BEGIN NEW(newTerm); newTerm.Init(AGRS.lastResult); AGRS.result:= newTerm; END pType; PROCEDURE (t: Character) Compare*(reference: Term; VAR lessEq,grEq: BOOLEAN); BEGIN WITH reference: Character DO lessEq:= t.value<=reference.value; grEq:= t.value>=reference.value; ELSE WITH reference: String DO lessEq:= t.value<=reference.value[0]; grEq:= t.value>=reference.value[0]; IF lessEq & grEq THEN grEq:= reference.value[1]=0X; END; ELSE lessEq:= FALSE; grEq:= FALSE; END; END; END Compare; PROCEDURE (t: String) Compare*(reference: AGRS.Term; VAR lessEq,grEq: BOOLEAN); VAR i: INTEGER; BEGIN WITH reference: Character DO lessEq:= t.value[0]<=reference.value; grEq:= t.value[0]>=reference.value; IF lessEq & grEq THEN lessEq:= t.value[1]=0X; END; ELSE WITH reference: String DO i:= 0; WHILE (t.value[i]=reference.value[i]) & (t.value[i]#0X) DO INC(i); END; lessEq:= (t.value[i]<=reference.value[i]); grEq:= (t.value[i]>=reference.value[i]); ELSE lessEq:= FALSE; grEq:= FALSE; END; END; END Compare; PROCEDURE (t: Number) Compare*(reference: Term; VAR lessEq,grEq: BOOLEAN); BEGIN WITH reference: Number DO lessEq:= t.value<=reference.value; grEq:= t.value>=reference.value; ELSE lessEq:= FALSE; grEq:= FALSE; END; END Compare; PROCEDURE (t: CharSet) Compare*(reference: Term; VAR lessEq,grEq: BOOLEAN); VAR i: INTEGER; BEGIN lessEq:= TRUE; grEq:= TRUE; WITH reference: CharSet DO FOR i:= 0 TO CharSetLength-1 DO IF t.value[i]-reference.value[i]#{} THEN lessEq:= FALSE; END; IF reference.value[i]-t.value[i]#{} THEN grEq:= FALSE; END; END; ELSE END; END Compare; PROCEDURE (t: Error) Compare*(reference: Term; VAR lessEq,grEq: BOOLEAN); BEGIN WITH reference: Error DO lessEq:= t.value<=reference.value; grEq:= t.value>=reference.value; ELSE lessEq:= FALSE; grEq:= FALSE; END; END Compare; PROCEDURE pEqual; VAR t1,t2: AGRS.Term; BEGIN t1:= argName1.Value(); t2:= argName2.Value(); IF AGRS.Equal(t1,t2) THEN TrueDef.Reduce; ELSE AGRS.Fail; END; END pEqual; PROCEDURE pLess; VAR t1,t2: AGRS.Term; lessEq,grEq: BOOLEAN; BEGIN t1:= argName1.Value(); WITH t1: AGRS.Atomic DO t2:= argName2.Value(); t1.Compare(t2,lessEq,grEq); IF lessEq & ~grEq THEN TrueDef.Reduce; RETURN END; END; AGRS.Fail; END pLess; PROCEDURE pGreater; VAR t1,t2: AGRS.Term; lessEq,grEq: BOOLEAN; oldStack: AGRS.TermStack; BEGIN t1:= argName1.Value(); WITH t1: AGRS.Atomic DO t2:= argName2.Value(); t1.Compare(t2,lessEq,grEq); IF ~lessEq & grEq THEN TrueDef.Reduce; RETURN END; END; AGRS.Fail; END pGreater; PROCEDURE pLessEq; VAR t1,t2: AGRS.Term; lessEq,grEq: BOOLEAN; BEGIN t1:= argName1.Value(); WITH t1: AGRS.Atomic DO t2:= argName2.Value(); t1.Compare(t2,lessEq,grEq); IF lessEq THEN TrueDef.Reduce; RETURN END; END; AGRS.Fail; END pLessEq; PROCEDURE pGrEq; VAR t1,t2: AGRS.Term; lessEq,grEq: BOOLEAN; BEGIN t1:= argName1.Value(); WITH t1: AGRS.Atomic DO t2:= argName2.Value(); t1.Compare(t2,lessEq,grEq); IF grEq THEN TrueDef.Reduce; RETURN END; END; AGRS.Fail; END pGrEq; PROCEDURE pNot; BEGIN AGRS.result:= argName1.Value(); IF AGRS.result.indirection=trueName THEN AGRS.result:= AGRS.Failure; ELSIF AGRS.result.indirection=AGRS.failName THEN AGRS.result:= TrueDef; ELSE AGRS.result:= NewError(NotLogicalType); END; AGRS.result.Reduce; END pNot; PROCEDURE pAnd; VAR eldest1: INTEGER; BEGIN AGRS.result:= argName1.Value(); IF AGRS.result.indirection=trueName THEN eldest1:= AGRS.eldestAsked; AGRS.result:= argName2.Value(); IF eldest1