Page 2 of 2
Posted: Sun Dec 11, 2005 7:42 am
by blueznl
NOT if you want to comment on sections of code, ie. do this
Code: Select all
OpenWindow( #1, _ ; window nr
10,10, _ ; x/y position
100,100, _ ; size
#PB_Window_SystemMenu, _ ; add a close button etc
"test") ; and the title
to
Code: Select all
OpenWindow( #1, 10,10,100,100,#PB_Window_SystemMenu,"test")
i agree that you wouldn't have to do parsing if don't need that comment option
Posted: Sun Dec 11, 2005 8:37 am
by Dare2
Parsing/Tokenising is best and perhaps useful for other nifty things.
However here is a quick and dirty (and untested) way. It just makes sure the ; is not inside a string. Rules are:
Open quotes on a physical line must have matching closed quotes.
The _ must be the last character except spaces (not any whitespace)
To allow any trailing white space would need to replacestring things like chr(9) with " " first.
Code: Select all
Global ptr
Dim wk.s(3)
wk(0)="Var.s = "+Chr('"')+"This is my string"+Chr('"')+" _"
wk(1)=" + chr(13)+chr(10) _ ; COMMENTED "
wk(2)=" + "+Chr('"')+"containing these ; _"+Chr('"')+" ; REMARKABLE :)"
wk(3)="Another Line"
Procedure.s GetNextLine()
If ptr<4 ; Emulate read or whatever process used
s.s=wk(ptr) ; to get individual lines
ptr+1
EndIf
Debug "--> "+s
If FindString(s,";",1)
For i=1 To Len(s)
If Mid(s,i,1)=Chr('"')
If tf=#True
tf=#False
Else
tf=#True
EndIf
ElseIf Mid(s,i,1)=";" And tf=#False
s=Left(s,i-1)
Break
EndIf
Next
EndIf
ProcedureReturn Trim(s)
EndProcedure
While ptr<4 ; not eof emulation :)
codeline.s=GetNextLine()
While Right(codeline,1)="_"
codeline = Left(codeline,Len(codeline)-1) + GetNextLine()
Wend
Debug codeline
Wend
Posted: Sun Dec 11, 2005 8:40 am
by PB
> NOT if you want to comment on sections of code
I know, but the concept is that space+underscore is an END OF LINE combo,
so having comments after it defeats that concept, which is my entire point.
That's the way it's always been with other apps, eg. Visual Basic.
Posted: Sun Dec 11, 2005 10:59 am
by blueznl
purebasic is not *just* another basic
hmmm... well, i've added it, on my pc it's not too slow (but your mileage may vary)
it's good for educational purposes to be able to comment on parts, i'd assume
perhaps i'll add an option to make it less smart but faster...
Posted: Sun Dec 11, 2005 5:27 pm
by Pupil
Ok, here's another one, as you can see i really like pointers

There's probably ways to improve this, but i wont do it..for now i'm just happy that it works
If you have many many lines in a row with linecontinuation and really long comments you will have to enlarge the string buffer that PB uses internally. Though i doubt this will happend, if one use >64kb of comments one should consider writing a book instead
Code: Select all
;
#EOL$ = Chr(13)+Chr(10)
; Init
Dim hash.b(255)
hash(' ') = 1
hash(';') = 1
hash(10) = 1
hash(13) = 1
hash('"') = 1
hash(9) = 1
hash(39) = 1
Procedure ParseFile(InFile.s, OutFile.s)
DefType.s comment, commentbuffer, dbgtext
DefType.l length, char, quote, pos, posline, linecontinuation
DefType.byte *ibuffer, *obuffer, *start, *endline, *iptr, *optr, *commentstart
If ReadFile(0, InFile)
length = Lof()
If length
*ibuffer = AllocateMemory(length+10) : *obuffer = AllocateMemory(length+10)
If *ibuffer And *obuffer
ReadData(*ibuffer, length)
Else
length = 0
EndIf
EndIf
CloseFile(0)
EndIf
If length = 0
ProcedureReturn 0
EndIf
*optr = *obuffer
*iptr = *ibuffer
Repeat
*start = *iptr
Repeat
char = *iptr\b & $ff
If char = '"' Or char = 39 ; Single or double quote
posline = 0
If quote
If quote = char ; Found matching quotes
quote = 0
EndIf
Else
quote = char
EndIf
ElseIf quote = 0
If char = ' ' Or char = 9 ; white space
If *iptr = *start And linecontinuation
*start + 1
EndIf
prevchar = ' ' : *iptr+1 : Continue
ElseIf char = ';' ; comment to end of line
*commentstart = *iptr
Repeat
; check for EOL or EOF
If *iptr\b = 10 Or *iptr\b = 0
If PeekB(*iptr-1) = 13
*endline = *iptr-1
Else
*endline = *iptr
EndIf
Break 2
EndIf
*iptr+1
ForEver
ElseIf char = '_' And prevchar = ' '
; Maybe it's a line continuation
posline = *iptr
ElseIf hash(char) = 0
posline = 0
EndIf
EndIf
; check for EOL or EOF
If char = 10 Or char = 0; End of line/file?
If *iptr > *start And PeekB(*iptr-1) = 13
*endline = *iptr-1
Else
*endline = *iptr
EndIf
Break
EndIf
prevchar = char
*iptr+1
ForEver
If posline
pos = posline
ElseIf linecontinuation
If *commentstart
pos = *commentstart
Else
pos = *endline
EndIf
Else
pos = *endline
EndIf
length = pos - *start
CopyMemory(*start, *optr, length) : *optr + length; + 1
If linecontinuation
If *commentstart
commentbuffer + PeekS(*commentstart, *endline-*commentstart)
EndIf
commentbuffer + #EOL$
If posline = 0
linecontinuation = 0
length = PokeS(*optr, comment+#EOL$) : *optr + length ;+ 1
length = PokeS(*optr, commentbuffer) : *optr + length ;+ 1
comment = "" : commentbuffer = ""
EndIf
ElseIf posline
linecontinuation = 1
If *commentstart
comment = PeekS(*commentstart, *endline-*commentstart)
Else
comment = ""
EndIf
ElseIf *iptr\b <> 0
PokeS(*optr, #EOL$) : *optr+2
EndIf
quote = 0 : prevchar = 0
posline = 0 : *endline = 0 : *commentstart = 0
*iptr+1
Until *iptr\b = 0
If *optr <> *obuffer
If CreateFile(0, OutFile)
WriteData(*obuffer, *optr-*obuffer)
CloseFile(0)
EndIf
EndIf
FreeMemory(*ibuffer) : FreeMemory(*obuffer)
ProcedureReturn 1
EndProcedure
file.s = OpenFileRequester("Select file", "", "All Files|*.*", 0)
If file <> ""
t1.l = GetTickCount_()
For i = 0 To 100
ParseFile(file, file+"$new.pb")
Next
t2.l = GetTickCount_()
MessageRequester("Time", Str(i-1)+" iterations took "+Str(t2-t1)+"ms.")
EndIf
Posted: Sun Dec 11, 2005 7:33 pm
by Trond
Here's my contribution. It's about twice as fast as the ones by blueznl and Konne.
Edit: Yes I know it generates "ugly" output, but so what, it's going through the compiler anyways!
Code: Select all
Procedure Apple(fnamein.s, fnameout.s)
ReadFile(0, fnamein)
InMem = AllocateMemory(Lof()+2)
OutMem = AllocateMemory(Lof())
Ln = Lof()
ReadData(InMem, Lof())
CloseFile(0)
I = INMem
Z = OUTMem
Ln = INMem + Ln
B = 0
CR = 0
While I < Ln
B = PeekB(I)
If B = '"' ;string
PokeB(Z, B)
Z + 1
Repeat
I + 1
B = PeekB(I)
If B = #CR ;We don't want linefeed inside string!
ProcedureReturn 1
EndIf
PokeB(Z, B)
Z + 1
Until B = '"' ;end of string
I + 1
Continue
EndIf
If B = 39 ;single quote
PokeB(Z, B)
Z + 1
Repeat
I + 1
B = PeekB(I)
If B = #CR ;We don't want linefeed inside quotes!
ProcedureReturn 2
EndIf
PokeB(Z, B)
Z + 1
Until B = 39 ;end of single quote
I + 1
Continue
EndIf
If B = ';'
Repeat
I + 1
B = PeekB(I)
If I > Ln ;In case there is only eof after comment
Continue
EndIf
Until B = #CR ;Linefeed at the end of a comment
PokeB(Z, B)
Z + 1
I + 1
Continue
EndIf
If PeekW(I) = '_ '
CR + 1
I + 2
Repeat
B = PeekB(I)
I + 1
If B = ';'
Repeat
B = PeekB(I)
I + 1
Until B = #CR
EndIf
Until B = #CR
I + 1
Continue
EndIf
If B = #CR
While CR
PokeW(Z, 2573)
Z + 2
CR - 1
Wend
EndIf
PokeB(Z, B)
Z + 1
I + 1
Wend
CreateFile(0, fnameout)
WriteData(OUTMem, Z-OUTMem)
CloseFile(0)
EndProcedure