September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -0,0 +1,119 @@
begin
% strips block comments from a source %
% the source is read from standard input and the result written to %
% standard output, The comment start text is in cStart and the ending %
% is in cEnd. %
% As strings are fixed length in Algol W, the first space in cStart/cEnd %
% is assumed to terminate the delimiter, i.e. the comment start/end %
% delimiters cannot contain spaces. %
% If non-blank, quote1 and quote2 are the string quote characters. %
% If escape is non-blank it indicates that quotes can be embedded in %
% string literals by preceding them with escape (as in C, java, etc.). %
procedure stripBlockComments( string(32) value cStart, cEnd
; string(1) value quote1, quote2, escape
) ;
begin
integer columnNumber, lineWidth;
string(256) line;
string(1) currChar;
string(1) newlineChar;
% gets the next source character %
procedure nextChar ;
begin
if columnNumber = lineWidth then begin
currChar := newlineChar;
columnNumber := columnNumber + 1
end
else if columnNumber > lineWidth then begin
readcard( line );
lineWidth := 256;
while lineWidth > 0 and line( lineWidth - 1 // 1 ) = " " do lineWidth := lineWidth - 1;
columnNumber := 1;
currChar := line( 0 // 1 )
end
else begin
currChar := line( columnNumber // 1 );
columnNumber := columnNumber + 1
end
end nextChar ;
% copy the current character and get the next %
procedure copyAndNext ;
begin
if currChar = newlineChar then write()
else writeon( currChar );
nextChar
end copyAndNext ;
% skips the current character and gets the next %
procedure skipAndNext ;
begin
if currChar not = newlineChar then currChar := " ";
copyAndNext
end skipAndNext ;
% handle a string literal %
procedure stringLiteral( string(1) value quote, escape ) ;
begin
copyAndNext;
while currChar not = quote and not XCPNOTED(ENDFILE) do begin
if escape <> " " and currChar = escape then copyAndNext;
if not XCPNOTED(ENDFILE) then copyAndNext
end while_have_more_string ;
if currChar = quote then copyAndNext
end stringLiteral ;
% returns true if the line continues with the specified text %
% false if not. %
logical procedure remainingLineStartsWith ( string(32) value text ) ;
begin
logical haveText;
integer lPos, wPos;
haveText := currChar = text( 0 // 1 );
lPos := columnNumber;
wPos := 1;
while haveText and wPos <= 32 and text( wPos // 1 ) not = " " do begin
if lPos >= lineWidth then begin
% past the end of the line %
haveText := false
end
else begin
% still have text on the line %
haveText := line( lPos // 1 ) = text( wPos // 1 );
wPos := wPos + 1;
lPos := lPos + 1;
end if_past_end_of_line_
end while_have_text_and_more_text ;
haveText
end remainingLineStartsWith ;
% skips the number of leading non-blank characters in the delimiter %
procedure skipDelimiter( string(32) value delimiter ) ;
begin
integer dPos;
dPos := 0;
while dPos < 32 and not XCPNOTED(ENDFILE) and delimiter( dPos // 1 ) not = " " do begin
dPos := dPos + 1;
skipAndNext
end while_not_at_end_of_delimiter
end skipDelimiter ;
newlineChar := code( 10 );
lineWidth := 0;
columnNumber := lineWidth + 1;
currChar := " ";
% allow the program to continue after reaching end-of-file %
ENDFILE := EXCEPTION( false, 1, 0, false, "EOF" );
% get the first source character %
nextChar;
% strip the comments %
while not XCPNOTED(ENDFILE) do begin
if currChar = " " then copyAndNext
else if remainingLineStartsWith( cStart ) then begin
% have a comment %
skipDelimiter( cStart );
while not remainingLineStartsWith( cEnd ) and not XCPNOTED(ENDFILE) do skipAndNext;
skipDelimiter( cEnd )
end
else if currChar = quote1 then stringLiteral( quote1, escape )
else if currChar = quote2 then stringLiteral( quote2, escape )
else copyAndNext
end while_not_at_eof
end stripBlockComments ;
% text stripBlockComments for C-style source %
stripBlockComments( "/*", "*/", """", "'", "\" )
end.

View file

@ -0,0 +1,126 @@
'strip block comment NESTED comments
'multi line comments
'and what if there are string literals with these delimeters?
'------------------------
'delimeters for Block Comment can be specified, exactly two characters each
'Three states: Block_Comment, String_Literal, Other_Text
'Globals:
Dim t As String 'target string
Dim s() As Byte 'source array
Dim j As Integer 'index into the source string s, converted to byte array
Dim SourceLength As Integer 'of a base 0 array, so last byte is SourceLength - 1
Dim flag As Boolean
Private Sub Block_Comment(sOpBC As String, sClBC As String)
'inside a block comment, expecting close block comment delimeter
flag = False
Do While j < SourceLength - 2
Select Case s(j)
Case Asc(Left(sOpBC, 1))
If s(j + 1) = Asc(Right(sOpBC, 1)) Then
'open block NESTED comment delimeter found
j = j + 2
Block_Comment sOpBC, sClBC
End If
Case Asc(Left(sClBC, 1))
If s(j + 1) = Asc(Right(sClBC, 1)) Then
'close block comment delimeter found
flag = True
j = j + 2
Exit Do
End If
'just a lone star
Case Else
End Select
j = j + 1
Loop
If Not flag Then MsgBox "Error, missing close block comment delimeter"
End Sub
Private Sub String_Literal()
'inside as string literal, expecting double quote as delimeter
flag = False
Do While j < SourceLength - 2
If s(j) = Asc("""") Then
If s(j + 1) = Asc("""") Then
'found a double quote within a string literal
t = t + Chr(s(j))
j = j + 1
Else
'close string literal delimeter found
flag = True
t = t + Chr(s(j))
j = j + 1
Exit Do
End If
End If
t = t + Chr(s(j))
j = j + 1
Loop
If Not flag Then MsgBox "Error, missing closing string delimeter"
End Sub
Private Sub Other_Text(Optional sOpBC As String = "/*", Optional sClBC As String = "*/")
If Len(sOpBC) <> 2 Then
MsgBox "Error, open block comment delimeter must be 2" & _
" characters long, got " & Len(sOpBC) & " characters"
Exit Sub
End If
If Len(sClBC) <> 2 Then
MsgBox "Error, close block comment delimeter must be 2" & _
" characters long, got " & Len(sClBC) & " characters"
Exit Sub
End If
Do While j < SourceLength - 1
Select Case s(j)
Case Asc(""""):
t = t + Chr(s(j))
j = j + 1
String_Literal
Case Asc(Left(sOpBC, 1))
If s(j + 1) = Asc(Right(sOpBC, 1)) Then
'open block comment delimeter found
j = j + 2
Block_Comment sOpBC, sClBC
Else
t = t + Chr(s(j))
j = j + 1
End If
Case Else
t = t + Chr(s(j))
j = j + 1
End Select
Loop
If j = SourceLength - 1 Then t = t + Chr(s(j))
End Sub
Public Sub strip_block_comment()
Dim n As String
n = n & "/**" & vbCrLf
n = n & "* Some comments /*NESTED COMMENT*/" & vbCrLf
n = n & "* longer comments here that we can parse." & vbCrLf
n = n & "*" & vbCrLf
n = n & "* Rahoo" & vbCrLf
n = n & "*/" & vbCrLf
n = n & "mystring = ""This is the """"/*"""" open comment block mark.""" & vbCrLf
'VBA converts two double quotes in a row within a string literal to a single double quote
'see the output below. Quadruple double quotes become two double quotes within the string
'to represent a single double quote within a string.
n = n & "function subroutine() {" & vbCrLf
n = n & "a = /* inline comment */ b + c ;" & vbCrLf
n = n & "}" & vbCrLf
n = n & "/*/ <-- tricky /*NESTED*/ comments */" & vbCrLf
n = n & "" & vbCrLf
n = n & "/**" & vbCrLf
n = n & "* Another comment." & vbCrLf
n = n & "*/" & vbCrLf
n = n & "function something() {" & vbCrLf
n = n & "}"
s = StrConv(n, vbFromUnicode)
j = 0
t = ""
SourceLength = Len(n)
Other_Text 'The open and close delimeters for block comment are optional ;)
Debug.Print "Original text:"
Debug.Print String$(60, "-")
Debug.Print n & vbCrLf
Debug.Print "Text after deleting comment blocks, preserving string literals:"
Debug.Print String$(60, "-")
Debug.Print t
End Sub