CodeCruncher

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

DAK

Betreff: CodeCruncher

BeitragDo, Feb 12, 2009 12:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Das hier ist dazu gedacht, Code zu komprimieren. Variablen-/Funktions-/Methoden- und Typenamen werden durch kürzere ersetzt. Desweiteren werden Tabs, leere Zeilen und unnötige Leerzeichen entfernt. So kann man sich das ganze manuelle Kürzen sparen.

Code: [AUSKLAPPEN]
SuperStrict

Framework brl.standardio
Import brl.linkedlist
Import BRL.FileSystem
Import BRL.Retro

Type TToken
   Global list:TList = CreateList()
   Field orig:String, repl:String, block:String
   Function Create:Byte(o:String,r:String,b:String)
      If Check(o,r)=0 Then Return 1
      Local tTemp:TToken = New TToken
      tTemp.orig=o
      tTemp.repl=r
      ListAddLast(list,tTemp)
      Return 1
   End Function
   Function Check:Byte(sName:String, sRepl:String)
      For Local tTemp:TToken = EachIn list
         If tTemp.orig=sName And Left(sRepl,1)=Left(tTemp.repl,1) Then Return 0
      Next
      Return 1
   End Function
EndType

Type Code Abstract
   Global lines:String[]
   Global tnumber:Int[]
   
   Function gettokens()
      Local block:String
      For Local i:Int = 0 To lines.length-1
         Local w:String=Replace(lines[i],";","")
         If Left(w,5)="Type " Then block:+"."+Mid(w,6,Instr(w," ",6)-6)
         If Left(w,9)="Function " block:+"."+Mid(w,6,Instr(w," ",10)-10)
         If Left(w,7)="Method " Then block:+"."+Mid(w,6,Instr(w," ",7)-7)
         If Left(w,7)="EndType" Then block=unblock(block)
         If Left(w,8)="End Type" Then block=unblock(block)
         If Left(w,11)="EndFunction" Then block=unblock(block)
         If Left(w,12)="End Function" Then block=unblock(block)
         If Left(w,9)="EndMethod" Then block=unblock(block)
         If Left(w,10)="End Method" Then block=unblock(block)
         If Left(w,6)="Local " Then getalltokens(Mid(w,7),0,block)
         If Left(w,7)="Global " Then getalltokens(Mid(w,8),1,block)
         If Left(w,6)="Field " Then getalltokens(Mid(w,7),2,block)
         If Left(w,9)="Function " Then getalltokens(Mid(w,10),3,block)
         If Left(w,5)="Type " Then getalltokens(Mid(w,6),4,block)
         If Left(w,7)="Method " Then getalltokens(Mid(w,8),3,block)
      Next
   End Function
   
   Function getalltokens(ln:String,typ:Int,block:String)
      ln=","+ln
      ln=Replace(ln,"  "," ")
      ln=Replace(ln,", ",",")
      ln=Replace(ln,") ",")")
      ln=Replace(ln,"( ","(")
      ln=Replace(ln,": ",":")
      ln=Replace(ln," :",":")
      Local repl:String
      If typ=0 Then repl="l"
      If typ=1 Then repl="g"
      If typ=2 Then repl="f"
      If typ=3 Then repl="u"
      If typ=4 Then repl="t"
      If typ=5 Then repl="m"
      Local par:Byte
      Local pos:Int=1
      Local pos2:Int
      If typ=3 Or typ=5 Then par=1
      While pos>0
         pos2 = Instr(ln,":",pos+1)
         
         Local iTempPos:Int = Instr(ln," ",pos+1)
         If pos2>iTempPos And iTempPos>0 Then pos2=iTempPos
         
         If pos2<1 Then pos2=iTempPos
         
         iTempPos = Instr(ln,"(",pos+1)
         If pos2>iTempPos And iTempPos>0 Then pos2=iTempPos
         
         If pos2<1 Then pos2=iTempPos
         Local c:Int=0
         If typ<>3 And typ<>5 Then
            For Local i:Int=1 To pos
               If Mid(ln,i,1)="(" Then c:+1
               If Mid(ln,i,1)=")" Then c:-1
            Next
         EndIf
         If c=0 Then
            Local orig:String=Mid(ln,pos+1,pos2-pos-1)
            If Len(orig)>3 Then
               Local cr:Byte = TToken.Create(orig,repl+tnumber[typ],block)
               tnumber[typ]:+cr
            EndIf
         EndIf
         If par=1 Then
            pos = Instr(ln,"(",pos+1)
            par=0
         Else
            pos = Instr(ln,",",pos+1)
         EndIf
      Wend
   End Function
   
   Function replacetokens()
      Local block:String
      For Local i:Int = 0 To lines.length-1
         If Left(lines[i],5)="Type " Then block:+"."+Mid(lines[i],6,Instr(lines[i]," ",6)-6)
         If Left(lines[i],9)="Function " block:+"."+Mid(lines[i],6,Instr(lines[i]," ",10)-10)
         If Left(lines[i],7)="Method " Then block:+"."+Mid(lines[i],6,Instr(lines[i]," ",7)-7)
         If Left(lines[i],7)="EndType" Then block=unblock(block)
         If Left(lines[i],8)="End Type" Then block=unblock(block)
         If Left(lines[i],11)="EndFunction" Then block=unblock(block)
         If Left(lines[i],12)="End Function" Then block=unblock(block)
         If Left(lines[i],9)="EndMethod" Then block=unblock(block)
         If Left(lines[i],10)="End Method" Then block=unblock(block)
         For Local tTemp:TToken = EachIn TToken.list
            If Instr(block,tTemp.block) Then lines[i]=ok(lines[i],tTemp.orig,tTemp.repl);Continue
            If Left(tTemp.orig,1)="g" Then lines[i]=ok(lines[i],Mid(block,2)+tTemp.orig,..
                                             Mid(block,2)+tTemp.repl)
         Next
      Next
   End Function
   
   Function unblock:String(block:String)
      Local blocknr:Int
      Local pos:Int=Instr(block,".")
      While pos>0
         blocknr:+1
         pos=Instr(block,".",pos+1)
      Wend
      pos=0
      For Local i:Int = 0 To blocknr-1
         pos=Instr(block,".",pos+1)
      Next
      Return Left(block,pos-1)
   End Function
   
   Function ok:String(ln:String,vname:String,tok:String)
      Local pos:Int=Instr(Lower(ln),Lower(vname))
      While pos>0
         Local lok:Byte=1
         Local rok:Byte=1
         If pos<>1 Then lok=testchr(Asc(Mid(ln,pos-1,1)))
         If pos+Len(vname)<>Len(ln) Then rok=testchr(Asc(Mid(ln,pos+Len(vname),1)))
         If lok=1 And rok=1 Then ln=replone(ln,vname,tok,pos)
         pos=Instr(Lower(ln),Lower(vname),pos+1)
      Wend
      Return ln
   End Function

   Function testchr:Byte(ch:Int)
      If ch=34 Then Return 0
      If ch>=65 And ch<=90 Then Return 0
      If ch>=97 And ch<=122 Then Return 0
      Return 1
   End Function

   Function replone:String(str:String,fnd:String,repl:String,pos:Int)
      pos = Instr(Lower(str),Lower(fnd),pos)
      Return Left(str,pos-1)+repl+Mid(str,pos+Len(fnd))
   End Function
   
   Function readall:Int(stream:TStream)
      tnumber = tnumber[..6]
      tnumber[0]=0
      tnumber[1]=0
      tnumber[2]=0
      tnumber[3]=0
      tnumber[4]=0
      tnumber[5]=0
      While Not Eof(stream)
         lines = lines[..lines.length+1]
         Local w:String = Trim(ReadLine(stream))
         lines[lines.length-1]=w
         While Instr(w,";")
            Local pos:Int=Instr(w,";")
            lines[lines.length-1] = Left(w,pos-1)+";"
            lines = lines[..lines.length+1]
            lines[lines.length-1] = Mid(w,pos+1)
            w=Mid(w,pos+1)
         Wend
      Wend
      Return lines.length
   End Function
   Function writeall(stream:TStream)
      Local out:String
      For Local i:Int = 0 To lines.length-1
         If Len(lines[i])>0 Then
            out:+Replace(lines[i],"  "," ")
         EndIf
         If Right(out,1)<>";" And Right(out,2)<>".." And Len(out)>0 Then
            WriteLine stream,Replace(out,"Then ","")
            out=""
         EndIf
         If Right(out,2)=".." Then out = Trim(Left(out, Len(out)-2))
      Next
   End Function
End Type

Local pathin:String = Input("Pfad des Originals: ")
Local pathout:String= Input("Pfad des Ziels:     ")

Print "read file"
Code.readall(ReadFile(pathin))
Print "get tokens"
Code.gettokens()
Print "replace tokens"
Code.replacetokens()
Print "write file"
Code.writeall(WriteFile(pathout))
Print "done"



der code mittels CodeCruncher komprimiert:
Code: [AUSKLAPPEN]
SuperStrict
Framework brl.standardio
Import brl.linkedlist
Import BRL.FileSystem
Import BRL.Retro
Type t0
Global g0:TList = CreateList()
Field f0:String, f1:String, f2:String
Function u0:Byte(o:String,r:String,b:String)
If u1(o,r)=0 Return 1
Local l0:t0 = New t0
l0.f0=o
l0.f1=r
ListAddLast(g0,l0)
Return 1
End Function
Function u1:Byte(u2:String, u3:String)
For Local l0:t0 = EachIn g0
If l0.f0=u2 And Left(u3,1)=Left(l0.f1,1) Return 0
Next
Return 1
End Function
EndType
Type t1 Abstract
Global g1:String[]
Global g2:Int[]
Function u4()
Local f2:String
For Local i:Int = 0 To g1.length-1
Local w:String=Replace(g1[i],";","")
If Left(w,5)="Type " f2:+"."+Mid(w,6,Instr(w," ",6)-6)
If Left(w,9)="Function " f2:+"."+Mid(w,6,Instr(w," ",10)-10)
If Left(w,7)="Method " f2:+"."+Mid(w,6,Instr(w," ",7)-7)
If Left(w,7)="EndType" f2=u8(f2)
If Left(w,8)="End Type" f2=u8(f2)
If Left(w,11)="EndFunction" f2=u8(f2)
If Left(w,12)="End Function" f2=u8(f2)
If Left(w,9)="EndMethod" f2=u8(f2)
If Left(w,10)="End Method" f2=u8(f2)
If Left(w,6)="Local " u5(Mid(w,7),0,f2)
If Left(w,7)="Global " u5(Mid(w,8),1,f2)
If Left(w,6)="Field " u5(Mid(w,7),2,f2)
If Left(w,9)="Function " u5(Mid(w,10),3,f2)
If Left(w,5)="Type " u5(Mid(w,6),4,f2)
If Left(w,7)="Method " u5(Mid(w,8),3,f2)
Next
End Function
Function u5(ln:String,typ:Int,f2:String)
ln=","+ln
ln=Replace(ln," "," ")
ln=Replace(ln,", ",",")
ln=Replace(ln,") ",")")
ln=Replace(ln,"( ","(")
ln=Replace(ln,": ",":")
ln=Replace(ln," :",":")
Local f1:String
If typ=0 f1="l"
If typ=1 f1="g"
If typ=2 f1="f"
If typ=3 f1="u"
If typ=4 f1="t"
If typ=5 f1="m"
Local par:Byte
Local pos:Int=1
Local l3:Int
If typ=3 Or typ=5 par=1
While pos>0
l3 = Instr(ln,":",pos+1)
Local l4:Int = Instr(ln," ",pos+1)
If l3>l4 And l4>0 l3=l4
If l3<1 l3=l4
l4 = Instr(ln,"(",pos+1)
If l3>l4 And l4>0 l3=l4
If l3<1 l3=l4
Local c:Int=0
If typ<>3 And typ<>5 Then
For Local i:Int=1 To pos
If Mid(ln,i,1)="(" c:+1
If Mid(ln,i,1)=")" c:-1
Next
EndIf
If c=0 Then
Local f0:String=Mid(ln,pos+1,l3-pos-1)
If Len(f0)>3 Then
Local cr:Byte = t0.u0(f0,f1+g2[typ],f2)
g2[typ]:+cr
EndIf
EndIf
If par=1 Then
pos = Instr(ln,"(",pos+1)
par=0
Else
pos = Instr(ln,",",pos+1)
EndIf
Wend
End Function
Function u7()
Local f2:String
For Local i:Int = 0 To g1.length-1
If Left(g1[i],5)="Type " f2:+"."+Mid(g1[i],6,Instr(g1[i]," ",6)-6)
If Left(g1[i],9)="Function " f2:+"."+Mid(g1[i],6,Instr(g1[i]," ",10)-10)
If Left(g1[i],7)="Method " f2:+"."+Mid(g1[i],6,Instr(g1[i]," ",7)-7)
If Left(g1[i],7)="EndType" f2=u8(f2)
If Left(g1[i],8)="End Type" f2=u8(f2)
If Left(g1[i],11)="EndFunction" f2=u8(f2)
If Left(g1[i],12)="End Function" f2=u8(f2)
If Left(g1[i],9)="EndMethod" f2=u8(f2)
If Left(g1[i],10)="End Method" f2=u8(f2)
For Local l0:t0 = EachIn t0.g0
If Instr(f2,l0.f2) g1[i]=ok(g1[i],l0.f0,l0.f1);Continue
If Left(l0.f0,1)="g" g1[i]=ok(g1[i],Mid(f2,2)+l0.f0,Mid(f2,2)+l0.f1)
Next
Next
End Function
Function u8:String(f2:String)
Local l7:Int
Local pos:Int=Instr(f2,".")
While pos>0
l7:+1
pos=Instr(f2,".",pos+1)
Wend
pos=0
For Local i:Int = 0 To l7-1
pos=Instr(f2,".",pos+1)
Next
Return Left(f2,pos-1)
End Function
Function ok:String(ln:String,u10:String,tok:String)
Local pos:Int=Instr(Lower(ln),Lower(u10))
While pos>0
Local lok:Byte=1
Local rok:Byte=1
If pos<>1 lok=u11(Asc(Mid(ln,pos-1,1)))
If pos+Len(u10)<>Len(ln) rok=u11(Asc(Mid(ln,pos+Len(u10),1)))
If lok=1 And rok=1 ln=u12(ln,u10,tok,pos)
pos=Instr(Lower(ln),Lower(u10),pos+1)
Wend
Return ln
End Function
Function u11:Byte(ch:Int)
If ch=34 Return 0
If ch>=65 And ch<=90 Return 0
If ch>=97 And ch<=122 Return 0
Return 1
End Function
Function u12:String(str:String,fnd:String,f1:String,pos:Int)
pos = Instr(Lower(str),Lower(fnd),pos)
Return Left(str,pos-1)+f1+Mid(str,pos+Len(fnd))
End Function
Function u14:Int(u15:TStream)
g2 = g2[..6]
g2[0]=0
g2[1]=0
g2[2]=0
g2[3]=0
g2[4]=0
g2[5]=0
While Not Eof(u15)
g1 = g1[..g1.length+1]
Local w:String = Trim(ReadLine(u15))
g1[g1.length-1]=w
While Instr(w,";")
Local pos:Int=Instr(w,";")
g1[g1.length-1] = Left(w,pos-1)+";"
g1 = g1[..g1.length+1]
g1[g1.length-1] = Mid(w,pos+1)
w=Mid(w,pos+1)
Wend
Wend
Return g1.length
End Function
Function u16(u15:TStream)
Local out:String
For Local i:Int = 0 To g1.length-1
If Len(g1[i])>0 Then
out:+Replace(g1[i]," "," ")
EndIf
If Right(out,1)<>";" And Right(out,2)<>".." And Len(out)>0 Then
WriteLine u15,Replace(out,"","")
out=""
EndIf
If Right(out,2)=".." out = Trim(Left(out, Len(out)-2))
Next
End Function
End Type
Local l8:String = Input("Pfad des Originals: ")
Local l9:String= Input("Pfad des Ziels:   ")
Print "read file"
t1.u14(ReadFile(l8))
Print "get tokens"
t1.u4()
Print "replace tokens"
t1.u7()
Print "write file"
t1.u16(WriteFile(l9))
Print "done"


6.453 Bytes wurden so zu schlanken 4.874 Bytes. ganz nett für codecompos und so[/code]
Gewinner der 6. und der 68. BlitzCodeCompo

Chrise

Betreff: Re: CodeCruncher

BeitragMi, Feb 25, 2009 12:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr geile Idee, ich werds gleich mal ausprobieren, wenn ich zuhause bin und eventuell noch mehr dazu schreiben.

Firstdeathmaker

BeitragMi, Feb 25, 2009 19:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Mach noch, das Zeilenumbrüche durch ";" ersetzt werden. Da jeder Zeilenumbruch glaube ich mehr Zeichen kostet als das ";"
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image

DAK

BeitragMi, Feb 25, 2009 19:15
Antworten mit Zitat
Benutzer-Profile anzeigen
das geht so einfach leider nicht, da sich nicht alles ;n lässt... versuchs mal... nimm irgendeinen code und ersetz alle zeilenumbrüche durch ;... das funktioniert leider nicht...

und immer das rausfiltern, was geht, das is mir zu viel arbeit...
Gewinner der 6. und der 68. BlitzCodeCompo

Artemis

BeitragMi, Feb 25, 2009 19:21
Antworten mit Zitat
Benutzer-Profile anzeigen
@Firstdeathmaker und DAK,

Zeilenumbrüche durch ; zu ersetzen ist nicht gut. Und dass Zeilenumbrüche mehr Bytes kosten ist auch nur bedingt richtig. Unter Linux (und ab Mac OS X) ist ein Zeilenumbruch Chr(10), unter Macs bis Version 9 Chr(13) und unter Windows Chr(13) Chr(10). Dass heißt nur unter Windows sind es ein Byte mehr als bei einem ;.

Du könntest als optimierung noch hinzufügen, dass er alle Chr(13) Chr(10) durch Chr(10) ersetzt.

DAK

BeitragMi, Feb 25, 2009 19:23
Antworten mit Zitat
Benutzer-Profile anzeigen
dann wärs doch nicht mehr platformunabhängig, oder?

dann würd das ganze doch nimmer mehr unter mac laufen, oder?
Gewinner der 6. und der 68. BlitzCodeCompo
 

klepto2

BeitragMi, Feb 25, 2009 20:07
Antworten mit Zitat
Benutzer-Profile anzeigen
netter Code Smile

zu den Zeilenumbrüchen. Man könnte es multiplattform lösen indem man einfach "~n" mit ";" ersetzt. Das ist allerdings ein sehr großer aufwand, denn:
- Import muss zb alleine am beginn des codes stehen (in einer Zeile funktioniert es nicht)
- Rem End Rem Blöcke funktionieren ebenfalls nicht in einer Zeile
-einzeilige kommentare müssten ebenfalls berücksichtigt werden

[Edit]
sry, hatte den post von DAK überlesen in dem er dies schon anspricht. Aber die Liste kann ja vielleicht als Checkliste herhalten falls sich doch einer drantraut Wink
Matrix Screensaver
Console Modul für BlitzMax
KLPacker Modul für BlitzMax

HomePage : http://www.brsoftware.de.vu

Firstdeathmaker

BeitragDo, Feb 26, 2009 12:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
- Rem End Rem Blöcke funktionieren ebenfalls nicht in einer Zeile
-einzeilige kommentare müssten ebenfalls berücksichtigt werden
Kommentare werden doch sowieso rausgeschmissen. Und für Import-Zeilen kann man ja ne abfrage machen.
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image
 

klepto2

BeitragDo, Feb 26, 2009 12:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Kommentare werden nicht rausgeschmissen, jedenfalls nicht soweit ich das gesehen und bei den Tests erfahren habe.
Matrix Screensaver
Console Modul für BlitzMax
KLPacker Modul für BlitzMax

HomePage : http://www.brsoftware.de.vu

Firstdeathmaker

BeitragDo, Feb 26, 2009 13:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm, dann wäre das aber noch ein Punkt den ich unbdingt einbauen würde.
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image

Smily

BeitragDo, Feb 26, 2009 13:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Was auch eine Idee wäre: Bei langen "buildin"-funktionsnamen, (z.B. drawimage, replace) prüfen, ob es sich lohnt, einen "wrapper" zu machen.

also z.B.

Code: [AUSKLAPPEN]
ln=Replace(ln," "," ")
ln=Replace(ln,", ",",")
ln=Replace(ln,") ",")")
ln=Replace(ln,"( ","(")
ln=Replace(ln,": ",":")
ln=Replace(ln," :",":")


zu
Code: [AUSKLAPPEN]
ln=f(ln," "," ")
ln=f(ln,", ",",")
ln=f(ln,") ",")")
ln=f(ln,"( ","(")
ln=f(ln,": ",":")
ln=f(ln," :",":")
function f(s1,s2,s3)
return replace(s1,s2,s3)
endfunction


in diesem speziellen fall lohnt es sich gerade nicht, da zwar ca 30 zeichen gespart, aber knapp 60 duch die neue funktion hinzukommen.
Wenn man allerdings viel mehr replaces im code hätte, würde sich das lohnen.
Lesestoff:
gegen Softwarepatente | Netzzensur | brain.exe | Unabhängigkeitserklärung des Internets

"Wir müssen die Rechte der Andersdenkenden selbst dann beachten, wenn sie Idioten oder schädlich sind. Wir müssen aufpassen. Wachsamkeit ist der Preis der Freiheit --- Keine Zensur!"
stummi.org

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group