Archive: Normal AVS Code -> loop() code translator


17th March 2004 08:46 UTC

Normal AVS Code -> loop() code translator
I wrote a little program that I think one of you might be able to use :)
It takes any (valid) AVS code and transforms it into either
- a nicely readable 1 assignment/command per line form,
- a not so nicely readable 1 assign()/command per line form
- a mix of assign()s and exec3()s which will most likely be unreadable but compatible to loop() :)
All of these forms are equivalent and as syntactically correct as the input ;)

You can then use the code in the following form:


loop(n, <output of my program>);


You can also use the generated code for if blocks if you want :)

if(cond, <output of my program for the true branch>, <output of my program for the false branch>);


I provided the source (VB6) so you can alter the program to suit your needs or even improve it ;)
Just give me credit if you use it in an AVS :)

You will need a VB6 runtime DLL (msvbvm60.dll) for this!
[edit]You can download it here[/edit]
[edit]I removed the OLE automation stuff so you only need msvbvm60.dll now.[/edit]
[edit]changed the interface a bit :)[/edit]

18th March 2004 03:01 UTC

From the way I read this, it sounds like a good thing... I will see how it works after a little bit of tinkering and report back later.

//added//
It works as far as I can tell, no matter what code I throw at it, it works. I could see how this would be useful for some odd ball things, but I personally can't see any use for it right now.

Request-Allow for comment ,// */ /*, support.
//added//


18th March 2004 03:30 UTC

// and /*...*/ should be no problem... this is treated as a part of the next command or of the next variable of the assignment
it will look a bit strange but it should work i think :)


a=b; /* comment */
c=d;

becomes

exec2(assign(a,b),assign(/* comment */
c,d))

which works, too :)

a=b; // comment
c=d;

becomes

exec2(assign(a,b),assign(// comment
c,d))


that' also valid, equivalent code

I could write something to filter the comments out if you want that. should be no problem :)

and btw: save your original code, it will be very hard to edit the code my program generates, as it does not structure it at all ;)

I'm going to make it convert something like "loop(1,a=b);" to "loop(1,assign(a,b));" so you can write whole code blocks and then let my program translate them. :) I'll need to make the whole thing recursive but that would allow one to write actually readable code with loop()s in it :)

18th March 2004 05:19 UTC

Nice idea.. but don't expect credit for making something easier that anyone could do otherwise. Do I credit Paint Shop Pro's authors when I use it to convert a .jpg to a .gif? I'd use this if you let me do so without credit.. otherwise I'd rather do it the long way than mention your name in an AVS comment when you had nothing to do with the actual preset or its code.

It is a really good idea though.. unfortunately I can't see any situation where I'd need to loop and enormous block of code without having a really slow preset.


18th March 2004 05:41 UTC

It's done :)

You can now check a box to filter comments and you can now write things like


loop(a=x+15,
a=b;
c=d;
e=f
);

which is transformed to

loop(assign(a,x+15),exec3(assign(a,b),assign(c,d),assign(e,f)))



or even cascade the loops

loop(y=x+15,
a=b;
loop(u=v-1,
c=d;
e=f
)
);

to get this:

loop(assign(y,x+15),exec2(assign(a,b),loop(assign(u,v-1),exec2(assign(c,d),assign(e,f)))))


The indentation is not necessary btw ;)

[edit]
jheriko: hmm just mention that you used the program somewhere in the comments, so people know you went the short way, i think that's just fair. ;)
and about the usage...
you could actually speed up your presets by using translated conditional blocks like

if(cond,a=b;c=d,e=f;g=h)
||
\/
if(cond,exec2(assign(a,b),assign(c,d)),exec2(assign(e,f),assign(g,h)))

and finally you can use big loops in Init or not so big loops in Frame.
[/edit]
[edit]
small bugfix: doesn't crash anymore when entering code with syntax errors :)
[/edit]

18th March 2004 12:49 UTC

bugfix
i fixed a (quite stupid :) ) bug in the comment filtering routine that caused it to loop infinitely (in other words: freeze ;) ) on nearly all combinations of comments (except those i tested *g*)


18th March 2004 16:07 UTC

It's much easier to just use assign()+assign()+assign()+... rather than nested exec3's and exec2's IMO.


18th March 2004 16:10 UTC

that's true but it's probably slower :)
since i wrote this program for loop()s at first i decided to use the exec()s
[edit]I'll make a checkbox for that :)[/edit]


18th March 2004 16:18 UTC

sorry for double posting but I forgot to add the new version :)
another improvement:
you can now choose not to translate the first level of commands, allowing you to translate whole preset blocks of this form:


code;
more=code;
loop(n,
code(looped);
count=count+1;
);
even=more+code;
still(code,here);

with the checkbox "Translate first level" unchecked this is translated to:

code;
more=code;
loop(n,exec2(code(looped),assign(count,count+1)));
even=more+code;
still(code,here);


[edit]added the new translation mode UnConeD suggested[/edit]

18th March 2004 16:50 UTC

Sweet stuff here! Really useful!


18th March 2004 21:53 UTC

Very handy. Thanks for making this!


19th March 2004 01:00 UTC

Very nice! This is an excellent tool that will be used A LOT (at least by me). It's so tricky to write code in nested loops and not have parentheses missing (or too many) that prevent compilation. This solves all of that! You are definitely going to get some credit in the credits of my next pack, because this makes creating code-driven AVS presets much more straightforward. I only wish it would have been out sooner, because I just got done making an extremely complicated preset that used a ton of code and I used plenty of time debugging mistyped code.

EDIT: I just tried converting about 200 lines of code in that preset to exec2/3's (just for fun). It worked perfectly, so I can almost 100% confirm there are no bugs in this program (although my original code had no comments, so that feature is untested by me).


19th March 2004 04:46 UTC

the comment filter should work flawlessly because it's not that complex :) the filtering is done before all parsing and just looks for /* and deletes everything until the next */ it finds. nested /* */ aren't valid in AVS anyway ;)
and it looks for // and deletes everything until the next CR+LF.
Erm ok there is one issue with the comment filter: please dont use the string "fgsfoihjoadas" anywhere in the input because it will be replaced by a slash :)

after all of these constructed mini-examples here's a real example that might give you an idea of what you could do with the program. here's one of my presets i wrote with my tool. It's mainly for testing purposes since it has no beat reaction or own movement :)
It's a reflective sphere and a plane. the camera can be controlled by the mouse (hold left mouse button down to pan the camera) and the keyboard (cursor keys to move around).

the main raytracing code is contained in these 2 nice if()s: :)


if(bplane,assign(isplane,1),exec3(exec3(exec3(assign(kdist,
(sqr(dx) + sqr(dy) + sqr(dz))),assign(kp , (2*dx*(ox-mx) +
2*dy*(oy-my) + 2*dz*(oz-mz))/kdist),assign(kq , (sqr(ox-mx)
+sqr(oy-my)+sqr(oz-mz)-sqr(rad))/kdist)),exec3(assign
(kdet,sqr(kp/2)-kq),assign(k1,-kp/2+sqrt(kdet)),assign(k2,-
kp/2-sqrt(kdet))),exec3(assign(k1,if(below
(k1,0),INFIN,k1)),assign(k2,if(below(k2,0),INFIN,k2)),assign
(ksphere,min(k1,k2)))),exec3(exec3(assign
(ax,dx*ksphere),assign(ikx,ax+ox),assign
(ay,dy*ksphere)),exec3(assign(iky,ay+oy),assign
(az,dz*ksphere),assign(ikz,az+oz)),exec3(assign(xdist,ikx-
mx),assign(ydist,iky-my),assign(zdist,ikz-mz))),exec2(assign
(distkugel,sqrt(sqr(xdist)+sqr(ydist)+sqr(zdist))),assign
(isplane,above(abs(rad-distkugel),epsilon)))));

if(isplane,exec2(exec3(exec3(assign(pa,0),assign
(pb,0),assign(pc,1)),exec3(assign(pd,-40),assign(k1,(-pa*ox-
pb*oy-pc*oz-pd)/(pa*dx + pb*dy + pc*dz)),assign(kplane,if
(below(k1,0),INFIN,k1))),exec3(assign(k,kplane),assign
(ix,dx*kplane+ox),assign(iy,dy*kplane+oy))),assign
(iz,dz*kplane+oz)),exec3(exec3(exec3(assign
(k,ksphere),assign(ar,invsqrt(sqr(ax)+sqr(ay)+sqr
(az))),assign(ax,ax*ar)),exec3(assign(ay,ay*ar),assign
(az,az*ar),assign(nx,ikx-mx)),exec3(assign(ny,iky-my),assign
(nz,ikz-mz),assign(nr,invsqrt(sqr(nx)+sqr(ny)+sqr
(nz))))),exec3(exec3(assign(nx,nx*nr),assign
(ny,ny*nr),assign(nz,nz*nr)),exec3(assign(bx,nx-(ax-
nx)),assign(by,ny-(ay-ny)),assign(bz,nz-(az-nz))),exec3
(assign(k1,(-pa*ikx-pb*iky-pc*ikz-pd)/(pa*bx + pb*by +
pc*bz)),assign(kplane2,if(below(k1,0),INFIN,k1)),assign
(ix,bx*kplane2+ikx))),exec2(assign(iy,by*kplane2+iky),assign
(iz,bz*kplane2+ikz))));


The first if() makes sure the sphere is only raytraced if the viewer is not on the wrong side of the plane.
The second if() does the reflection calculations only if the sphere is actually hit (anyone got better code for determining this instead of the approximating code? :) ).

The non-translated code is provided in the comments after the DM and the Texer II respectively.

19th March 2004 05:16 UTC

forgot the attachment *g*


19th March 2004 09:39 UTC

download site
i made a download site for AVSTrans here


19th March 2004 12:21 UTC

hm, usefull, really!
this programm is very helpfull when using e.g. whittaker iteration (or othe iterations) on raytracing presets.
some kind of back-converter that can convert the generated code back mortal winamp code.
nochwas: tomy, du kannst doch so gut proggen. bitte schreib mal ein programm welches syntax-fehler im AVS code markiert. fehlersuche in superscopes etc. stress manchmal wirklich, da bei einem fehler einfach garnix gemacht wird. bis gleich!


24th March 2004 23:57 UTC

Never thought of using code inside ifs like that to optimise stuff so heavily. I suppose containing massive blocks of code inside ifs is a really efficient way of dealing with some things.


25th March 2004 08:30 UTC

@your-dentist
(he asked me to write an AVS syntax checker)
Such a syntax checker is already integrated in AVS.
Open Settings/Debug Window... and check the "Log compile errors" checkbox.
AVS will then display all erronous code in the "Recent eval code errors" box as soon as you change something in the code in question

So nen Syntaxchecker ist schon in AVS integriert.
Geh mal auf Settings/Debug Window... und aktivier mal "Log compile errors"
Dann zeigt dir AVS sämtlichen fehlerhaften code in der "Recent eval code errors" Box sobald du den fragliche code änderst.


27th March 2004 04:22 UTC

http://zevensoft.no-ip.com/filedump/avs/codeconvert.exe

Can convert VB6 code into AVS.
Atm only supports dim, global, private, for/next, and =.
Other statements will be left intact.

Example:


dim a(100)
global b()

for n = 0 to 100
a((n+1)%100) = b(n)
next n

Will create avs code that does the same.

Note that you need to enable interlaced arrays for dynamic
arrays, as I haven't coded a dynamic memory manager yet. And I cbf coding it either.

27th March 2004 11:14 UTC

Nice idea Zevensoft

I picked out some advantages and disadvantages of using your program instead of mine:

advantages:
- you don't have to learn the AVS language
- you can use (parts of) existing VB6 programs directly in AVS
- easy (g)megabuf handling

disadvantages:
- you have to learn VB6 ;)
- with the easy (g)megabuf handling of your program you don't know what is in your (g)megabuf and where, so you have to write the whole code in VB6
- you have to convert AVS code to VB6 (which your program can't do yet) to use it in your program
- you don't work close to the AVS language anymore and it's hard to optimize your program's output. this is also true for my program, but you can optimize before translating as my program doesn't add any extra commands. I tested that: "a=b; c=d;" and "exec2(assign(a,b),assign(c,d));" both generate 37 bytes code
- your program always creates assign(...)+assign(...), which is slighty slower than the exec2/3() blocks my program creates (feel free to take the "mkexecs" function from my program to achieve this, it needs to be called until the array of commands has only 1 element left)


While UBound(outField) > 0
outField = mkexecs(outField)
Wend
tmpExecForm = outField(0)

(assumes LBound(outField) = 0)
- your program only supports a finite number of flow control operations. For example if Nullsoft decided to implement something like While...Wend from VB6 in AVS, you have to change your program. I don't need to change mine because it accepts assignments inside all functions. you could for example write

a=b;
c=getosc(
d=e
,
f=g
,
h=i
)

in my program and it would convert it to strange but working AVS code.

Bugs(or maybe not yet implemented features? :) ) I found:

That code example you supplied is not VB6 but it looks like VB6
VB6 needs ReDims for dynamic arrays and you write MOD instead of %
try this for the modulo problem:

Temp = Join(Split(" mod ", Input, , vbTextCompare), "%")

this replaces " mod " (case insensitive) by "%", which should be enough since the VB6 IDE formats the code this way...

try to convert

a=b:b=c

it won't work... multiple commands in 1 line are sometimes needed in order to preserve clarity

btw your program generates an "index out of range" error for this code:

for i=1 to 2
a=b
next i

fix this :)

Your program doesn't support comments (yet). Try using a modified version of the FilterComments() function in my program if you want. (assume FilterAll = True and remove everything that is not executed with this assumption to leave out all the stuff i use for the Comment Codes)

btw there's a new version (1.8.01) on my page and I will put 1.9.00 there, soon, which will support easier megabuf assignments. I'm starting to write this now :)

[edit]
Hmm this was 2 lines of code added.
The uploading was the hardest part :)
[/edit]

27th March 2004 19:29 UTC

I can't seem to get the "Auto Clipboard" feature working, which is a shame because it sounds like a really useful idea. I've tried playing with the checkboxes and the //$DoAutoClipboard comment but copying and pasting code does not run it through your converter no matter what I do.

EDIT: I'm using version 1.9.00.


27th March 2004 20:20 UTC

Hmm it works for me...
I started AVSTrans and activated the "Auto-Clipboard mode" checkbox and copied this into the clipboard:


//$DoAutoClipboard
a=b

and pasted it somewhere else and got

assign(a,b)


[edit]
the DoAutoClipboard comment needs to be in the clipboard, NOT in the input box
[/edit]

Auto-Clipboard mode scans the clipboard once in a second, this means that you'll need to wait up to 1 second to get the converted code, so don't paste too fast :)

Make sure you checked the "Translate first level" checkbox if you use normal AVS code as input (without something like "loop(n,a=b)")

Also check the spelling of "//$DoAutoClipboard" and try to put it in the first line (should normally not be necessary but it's worth a try)
Another problem might be clipboard managers... I don't have one of them installed so i don't know how they work but they might interfer with the Auto-Clipboard mode of my program.

Try to normally convert the code in question using the input box and see if there are errors (normally auto-clipboard mode should do exactly the same as pasting the code into the input box and copying it from the output box, but something might have been messed up, so please try that too :) )

27th March 2004 22:49 UTC

Oh, OK it works now. I thought the comment code only had to be in the input box for some reason.


27th March 2004 23:55 UTC

i made the DoAutoClipboard thing to prevent AVSTrans from translating everything in the clipboard: URLs, your documents, pictures :)

[edit]
I updated the CHANGELOG on the website (not in the .zip) and removed some ambiguities regarding the placement of the DoAutoClipboard comment :)
[/edit]


4th April 2004 07:01 UTC

new version
I added a new feature to AVSTrans: Replacements.
You can now add special Comment Codes to your code that tell AVSTrans to replace any occurance of a string in the code by another string. Read the CHANGELOG for details
You can download AVSTrans 1.10.00 here


7th April 2004 17:35 UTC

i think this is pretty pointless...people should be able to translate their code themselves. also, exec2(,) and exec3(,,) are useless afaik, cos assign(,)+assign(,)+assign(,) ... does the same thing without the extra computation of another function.


7th April 2004 17:58 UTC

the AVS evaluator compiles your code to machine code and stores it for execution
knowing that, it should be clear that it's actually the other way round:
that + sign generates an ADD instruction, while the execs are just another way to write semicolon separated assign()s. they are not "calculated"
you can also test it:
make a new .avs, add a SSC, write some code in it, look at the Eval code stats in the debug window.
it says xxxx+xxx bytes code
next, copy your code to AVSTrans and let it translate it into execs.
replace the SSC code with these execs and look at the Eval code stats in the debug window again:
no change :eek:
still the same code length, and thus the same execution speed

now try the same with the assign+assign method and you should notice an increase in the code length, which is caused by the ADD instructions i mentioned above.

and about translating your code manually: you did probably not read the whole thread as i posted a quite complex example (raytracing with some if blocks to increase speed) try that manually :) if you do this without errors, you're a genius
the code will probably be erronous because you forgot a bracket, comma or the likes somewhere
the example is here.


8th April 2004 20:43 UTC

Atero, I think I've said this about a hundred times or so: stop nagging about extra function calls or whatever in AVS. And now, you don't have the excuse of not having the source code. Get yourself the 5.02 AVS SDK and take a look at nseel-cfunc.c. Now you know exactly what all that code in AVS does.

Almost all functions now result in direct compiled code without jumps or calls. Only complicated math operations such as the arctrig functions or pow/exp cause actual jumps into external code.


9th April 2004 13:47 UTC

I am confuse. sorry I don't undrastand some parts of it.


10th April 2004 05:38 UTC

Originally posted by Atero
i think this is pretty pointless...people should be able to translate their code themselves. also, exec2(,) and exec3(,,) are useless afaik, cos assign(,)+assign(,)+assign(,) ... does the same thing without the extra computation of another function.
what computation does exec2/3 do?

what computation does + do?

is + a function?

think about it carefully. i dont even need to look in the source on this one.

10th April 2004 20:07 UTC

mmmh

+ is a floating point add, which is a few cycles, exec2 is just fetching instructions and putting the last value in the active register, so its practically nothing in cpu cycles. But you would have to do a fair bit of it do notice a difference.


10th April 2004 21:18 UTC

like 20 lines of code in a loop(100)? :)


11th April 2004 03:44 UTC

i heard it the first time, christ...x_x


12th April 2004 03:31 UTC

this kicks ass:)
probably gona save me alot of nervous breakdowns:D

what about support for stuff like
a<b
a==b
for the ifs?
i just hate the damn equal(bla,bla)stuff

nah this is a stupid idea i gues cause theat would just make it another language, nm:)

nice work dood:thubs up:


12th April 2004 17:14 UTC

hmm... a<b and a==b and the likes would be quite hard to code. I'd have to parse the whole string for something like == > <
i'd also have to respect precedence
(a+b)==(c+d)
and
a+b==c+d
don't have to be the same :)

atm all functions are treated equally: first, they're split to command name and parameter list
commandname(parameterlist)
the program looks for commas and keeps track of the bracket level. If it finds a comma and the current bracket level is 0, the string up to the comma is taken as a command block and translated recursively. when the translation returns, the command is composed from the the command name and the translated parameters.

If someone has a good parsing/replacement algorithm for the comparisons, i'll put it into the program (provided, i have the permission to do so :) ).
Needed is basically something that takes an AVS command block as input and replaces all occurances of some+term-goes*here==another+term-goes*here by equal(some+term-goes*here,another+term-goes*here)
The programming language can be VB, VBA, PHP, Perl, C/++, Pascal/Delphi/Kylix, J(ava)Script, VBScript, and maybe even Java :)
(ordered from best to worst :) )

I also found out that some bugs cause certain combinations of code not to translate to what i intended, namely:


loop(5,
somefn(param);
otherfn(param);
);

does not translate correctly


a=b+loop(5,
assign(a,b);
assign(a,b);
c=d;
);

generates an ERR

both result from a simple (and quite stupid :D ) bug and are fixed in 1.10.01
see CHANGELOG.txt for details :)

12th April 2004 18:32 UTC

what about support for stuff like
a<b
a==b
for the ifs?
i just hate the damn equal(bla,bla)stuff
That would be awesome, above(bla,bla) and that crap wastes code space, and those brackets are so annoying.

13th April 2004 13:28 UTC

Whooo! Now maybe this'll finally help me understand the whole array thing!


13th April 2004 14:22 UTC

array thing? you mean (g)megabuf?
it's simple:
A (g)megabuf can be seen as a collection of variables (1 million of them :) )
that can be addressed by using an index.

Syntax:
without AVSTrans:
local (only available in this specific component):


assign(megabuf(index), value); // assigns "value" to megabuf entry #index
variable = megabuf(index); // assigns the value of megabuf entry #index to "variable"


global (shared between the components)
local (only available in this specific component):

assign(gmegabuf(index), value); // assigns "value" to gmegabuf entry #index
variable = gmegabuf(index); // assigns the value of gmegabuf entry #index to "variable"


with AVSTrans 1.11.00:
like the above or:
local:

megabuf[index] = value; // assigns "value" to megabuf entry #index
variable = megabuf[index]; // assigns the value of megabuf entry #index to "variable"


global:

gmegabuf[index] = value; // assigns "value" to gmegabuf entry #index
variable = gmegabuf[index]; // assigns the value of gmegabuf entry #index to "variable"

note that the above only counts for the newest version (1.11.00) where I fixed that thing i mentioned in the 1.09.00 CHANGELOG entry about those brackets that were needed before 1.11.00.

13th April 2004 15:11 UTC

i can see myself getting too used to coding with this, then traslating :)


14th April 2004 05:40 UTC

there is a serious bug in 1.11.00!
everything is fine as long as you dont use the recursing parser (i.e. write things like loop(n,a=b); )
I'm working on a solution just now

[edit]
The new version (1.11.01) is ready, and is available here
The bug mentioned above isn't limited to the recursing parser, but everything should work fine now with the new version.
[/edit]


14th April 2004 17:09 UTC

1.11.02 is available and fixes another bug in the recursing parser. i think i've got all of them now :)

[edit]
1.11.02 is done and implements a bracketing check that will mark errors instead of just displaying nothing or even crashing on them ;)
if it finds a bracketing error, it marks the whole block with


BRACKETS(n)->erronous code<-BRACKETS

where n is the number of brackets missing (negative numbers mean too much brackets)
no translations are done if there is a bracketing error
[/edit]

[edit]
yet another version (1.11.04) *argh*
After all these structural changes I could now finally implement megabuf assignments the way i meant them to be :)

megabuf(index)=value

with *round* brackets instead of square brackets :)
They already worked in 1.11.02 but with the restriction I explained in the 1st addition to the 1.09.00 entry
[/edit]

15th April 2004 01:47 UTC

why do you use the bufdist thing in texer2 in your example?
imho it's easier and fSaster to use


megabuf(t);
megabuf(t+n);
megabuf(t+n2); // etc.

...where t varies from 0 to (n-1).
n*2, n*3 etc can be pre-calculated on ini.
ex.: buggyAVS2 >> particles-II

15th April 2004 02:27 UTC

The base structure of that texer is quite old *g*
I'd write this differently if i did this now :)
It's just 5 points in that texer2... I really don't need to optimize that, do i? :)
atm I'm working on a pattern replacement algorithm for AVSTrans, which would allow writing things like


//$AVSTrans_Replacement_Pattern=variable([a-z*/-+()])->megabuf($1+n2)
a=variable(b);
variable(c)=d;

so i think I'm going to switch over to the t+n2 technique, because the interleaving technique(t*n+1) i'm using now is quite hard to pre-cache/optimize if i use pattern matching :(

15th April 2004 04:48 UTC

AVSTrans 1.12.00 is out :)
Most noticable new feature: Regular Expression Matching/Replacement .
I'm using the RegEx Object from VBScript for that.
For a description of the available Expressions look at the corresponding MSDN site.

The syntax is


//$AVSTrans_Replacement_Pattern=pattern->replacevar

the replacevar may contain things like $1 to get the remembered matches described in the "(pattern)" line in the MSDN document.

a (working) example :

//$AVSTrans_Replacement_Pattern=variable\(([^\)]*)\)->megabuf($1+n2)
a=b;
variable(ab)=d;
e=f

this translates to

a=b;
assign(megabuf(ab+n2),d);
e=f