DIRECTORY RegExpFindCompile, TextFind USING [MalformedPattern], TextLooks USING [Looks], RegExpFindPrivate USING [ParseTree, Code, CodeContent, PatternOpCodeArray, PatternDataArray, PatternNextArray, PatternLooksArray, IgnoreLooks, ParseTreeContent, OpCode, Index]; RegExpFindCompileImpl: CEDAR PROGRAM IMPORTS TextFind EXPORTS RegExpFindCompile = { OPEN RegExpFindPrivate; Compile: PUBLIC PROC [p: ParseTree] RETURNS [code: Code] = { CompileIt: PROC [p: ParseTree, self, next: Index] = { WITH p SELECT FROM x: REF ParseTreeContent.concat => { FOR l: LIST OF ParseTree _ x.concats, l.rest UNTIL l = NIL DO IF l.rest = NIL THEN CompileIt[l.first, self, next] ELSE { middle: Index _ Alloc[]; CompileIt[l.first, self, middle]; self _ middle; }; ENDLOOP; }; x: REF ParseTreeContent.char => Set[self, IF x.looks = IgnoreLooks THEN matchChar ELSE matchCharLooks, x.looks, C2N[x.char], next]; x: REF ParseTreeContent.charIC => Set[self, IF x.looks = IgnoreLooks THEN matchCharIC ELSE matchCharLooksIC, x.looks, C2N[x.char], next]; x: REF ParseTreeContent.class => Set[self, IF x.looks = IgnoreLooks THEN matchClass ELSE matchClassLooks, x.looks, x.classNumber, next]; x: REF ParseTreeContent.anyChar => Set[self, IF x.looks = IgnoreLooks THEN matchAnyChar ELSE matchAnyCharLooks, x.looks, notUsed, next]; x: REF ParseTreeContent.nodeBreak => Set[self, matchNodeBreak, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.skipToNodeBreak => Set[self, IF x.looks = IgnoreLooks THEN skipToNodeBreak ELSE skipToNodeBreakLooks, x.looks, notUsed, next]; x: REF ParseTreeContent.beginNode => Set[self, matchBeginNode, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.fail => Set[self, fail, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.succeed => Set[self, succeed, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.noOp => Set[self, noOp, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.skipOverClass => Set[self, IF x.looks = IgnoreLooks THEN skipOverClass ELSE skipOverClassLooks, x.looks, x.classNumber, next]; x: REF ParseTreeContent.skipOverChar => Set[self, IF x.looks = IgnoreLooks THEN skipOverChar ELSE skipOverCharLooks, x.looks, C2N[x.char], next]; x: REF ParseTreeContent.skipOverCharIC => Set[self, IF x.looks = IgnoreLooks THEN skipOverCharIC ELSE skipOverCharLooksIC, x.looks, C2N[x.char], next]; x: REF ParseTreeContent.skipOver => -- ERROR TextFind.MalformedPattern[invalidNot,0]; ERROR TextFind.MalformedPattern[toobig]; x: REF ParseTreeContent.skipToChar => Set[self, IF x.looks = IgnoreLooks THEN skipToChar ELSE skipToCharLooks, x.looks, C2N[x.char], next]; x: REF ParseTreeContent.skipToCharIC => Set[self, IF x.looks = IgnoreLooks THEN skipToCharIC ELSE skipToCharLooksIC, x.looks, C2N[x.char], next]; x: REF ParseTreeContent.skipToString => { endOfStringInstructions: Index _ Alloc[]; stringInstructions: Index _ Alloc[]; Set[endOfStringInstructions, endOfSkipToString, IgnoreLooks, notUsed, next]; Set[self, skipToString, IgnoreLooks, notUsed, stringInstructions]; CompileIt[x.p, stringInstructions, endOfStringInstructions]; }; x: REF ParseTreeContent.skipTo => -- ERROR RegExpFind.MalformedPattern[invalidNot,0]; ERROR TextFind.MalformedPattern[toobig]; x: REF ParseTreeContent.skipToEnd => Set[self, skipToEnd, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.skipToBeginning => Set[self, skipToBeginning, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.closure => { body: Index _ Alloc[]; Set[self, closure, IgnoreLooks, body, next]; CompileIt[x.p, body, self]; }; x: REF ParseTreeContent.carefulClosure => { body: Index _ Alloc[]; bodyPlusOne: Index _ Alloc[]; check: Index _ Alloc[]; Set[self, carefulClosure, IgnoreLooks, body, next]; Set[check, carefulClosureEnd, IgnoreLooks, self, self]; CompileIt[x.p, body, check]; }; x: REF ParseTreeContent.greedyClosure => { body: Index _ Alloc[]; Set[self, greedyClosure, IgnoreLooks, next, body]; CompileIt[x.p, body, self]; }; x: REF ParseTreeContent.carefulGreedyClosure => { body: Index _ Alloc[]; bodyPlusOne: Index _ Alloc[]; check: Index _ Alloc[]; Set[self, carefulGreedyClosure, IgnoreLooks, next, body]; Set[check, carefulGreedyClosureEnd, IgnoreLooks, self, self]; CompileIt[x.p, body, check]; }; x: REF ParseTreeContent.alt => { FOR l: LIST OF ParseTree _ x.alts, l.rest UNTIL l = NIL DO IF l.rest = NIL THEN CompileIt[l.first, self, next] ELSE { instr: Index _ Alloc[]; nextAlt: Index _ Alloc[]; Set[self, alt, IgnoreLooks, nextAlt, instr]; CompileIt[l.first, instr, next]; self _ nextAlt; }; ENDLOOP; }; x: REF ParseTreeContent.field => { instr: Index _ Alloc[]; endInstr: Index _ Alloc[]; Set[self, fieldStart, IgnoreLooks, x.number, instr]; IF x.bound # -1 THEN { extraInstr: Index _ Alloc[]; Set[instr, boundNodeBreaks, IgnoreLooks, x.bound, extraInstr]; instr _ extraInstr; }; Set[endInstr, fieldEnd, IgnoreLooks, x.number, next]; CompileIt[x.p, instr, endInstr]; }; x: REF ParseTreeContent.fieldEquals => Set[self, fieldEquals, IgnoreLooks, x.number, next]; x: REF ParseTreeContent.fieldEqualsIC => Set[self, fieldEqualsIC, IgnoreLooks, x.number, next]; x: REF ParseTreeContent.beginALL => Set[self, fieldStart, IgnoreLooks, 0, next]; x: REF ParseTreeContent.endALL => Set[self, fieldEnd, IgnoreLooks, 0, next]; x: REF ParseTreeContent.beginAll => Set[self, beginAll, IgnoreLooks, 0, next]; x: REF ParseTreeContent.endAll => Set[self, endAll, IgnoreLooks, 0, next]; ENDCASE => ERROR; }; codePC: Index _ 0; codeSize: Index _ 0; StandardSizeIncrement: Index = 100; notUsed: NAT = 0; C2N: PROC [c: CHAR] RETURNS [n: NAT] = INLINE { n _ c - 0C; }; Alloc: PROC [] RETURNS [pc: Index] = { pc _ codePC; IF pc >= codeSize THEN { newCodeSize: INT _ codeSize*2 + StandardSizeIncrement; newCode: Code _ NEW[CodeContent _ [ NEW[PatternOpCodeArray[newCodeSize]], NEW[PatternLooksArray[newCodeSize]], NEW[PatternDataArray[newCodeSize]], NEW[PatternNextArray[newCodeSize]]]]; IF codeSize > 0 THEN FOR i: Index IN [0..pc) DO newCode.opCodes[i] _ code.opCodes[i]; newCode.looks[i] _ code.looks[i]; newCode.data[i] _ code.data[i]; newCode.next[i] _ code.next[i]; ENDLOOP; code _ newCode; codeSize _ newCodeSize; }; codePC _ codePC+1; }; Set: PROC [pc: Index, opCode: OpCode, looks: TextLooks.Looks, data: NAT, next: Index] = { code.opCodes[pc] _ opCode; code.looks[pc] _ looks; code.data[pc] _ data; code.next[pc] _ next; }; first: Index _ Alloc[]; CompileIt[p, first, 0]; }; }. PRegExpFindCompileImpl.mesa Last Edited by: Nix, December 21, 1983 6:02 pm Κ˜Jšœ™J™.J˜šΟk ˜ Jšœ˜Jšœ œ˜"Jšœ œ ˜Jšœœ™˜°J˜—JšΟbœœœ˜%Jšœ ˜Jšœ˜Jšœ˜J˜šΟnœœœœ˜=šŸ œœ&˜5šœœœ˜codešœœ˜#š œœœœœ˜=šœ œ˜K˜—šœ˜K˜K˜!K˜K˜—Kšœ˜—K˜—šœœ˜Kšœ œœ œ-˜c—šœœ˜!Kšœ œœ œ/˜g—šœœ˜ Kšœ œœ œ0˜g—šœœ˜"Kšœ œœœ,˜e—šœœ˜$Kšœ6˜6—šœœ$˜*Kšœ œœœ/˜k—šœœ˜$Kšœ6˜6—šœœ˜ Kšœ,˜,—šœœ˜"Kšœ/˜/—šœœ˜Kšœ,˜,—šœœ"˜(Kšœ œœœ3˜m—šœœ!˜'Kšœ œœœ0˜i—šœœ#˜)Kšœ œœœ2˜m—šœœ˜$Kšœœ)˜1Kšœ$˜)—šœœ˜%Kšœ œœ œ.˜e—šœœ!˜'Kšœ œœœ0˜i—šœœ#˜)K˜)K˜$KšœL˜LKšœB˜BK˜˜>K˜K˜—Kšœ5˜5K˜ K˜—šœœ ˜&Kšœ4˜4—šœœ"˜(Kšœ6˜6—šœœ˜#Kšœ,˜,—šœœ˜!Kšœ*˜*—šœœ˜#Kšœ*˜*—šœœ˜!Kšœ(˜(—Kšœœ˜—K˜—K˜K˜Kšœ#˜#Kšœ œ˜š Ÿœœœœœœ˜/K˜ K˜—šŸœœœ˜&K˜ šœœ˜Jšœ œ&˜6šœœ˜#Jšœ#˜&Jšœ!˜$Jšœ!˜$Jšœ#˜&—šœ˜šœ œ ˜J˜%Jšœ!˜!Jšœ˜Jšœ˜Jšœ˜——J˜Jšœ˜J˜—J˜J˜—šŸœœ;œ˜YJ˜J˜J˜J˜J˜—J˜J˜J˜—J˜˜J˜——…—φe