Comments are closed

cJass on the Google Code.
Our BugTracker (recommend to post bugreports and features request there).
Beta tester notes.

all times are GMT +04:00
Latest posts

Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [21] 22 23 24 25 26 27

posted at 14/09/09 10:10
Guest

where can I find the manual?
I'm translating it now, it will soon be available on this site.
VD

posted at 14/09/09 02:50
Dark Dragon

ADOLF!
that example which will use temp var is fine with me coz well its still fast...
while ur fixing textmacros plz as well fix externals ;)
as well my fav features like def arguments, no more function keyword for func pointers and (true)? 1 : 0
all that would be nice :]
however take ur time and greets!
~DD

posted at 13/09/09 20:50
Strilanc

Declarations with initialization are still being moved incorrectly, causing bugs if you aren't aware of it.
For Example:
: real r
: r = 2
: real s = r
becomes:
: real r
: real s = r //crash
: r = 2
instead of:
: real r
: real s
: r = 2
: s = r
Thank you for report, we'll fix that. For now I don't know what way will ADOLF choose, but he will certainly fix it =)
VD

posted at 13/09/09 19:23
weaaddar

There seems to be a bug iwth enum types.
If you declare an enum it'll work without consideration of prefix or a value assignment.
I.e.
enum(AgentTypes)
{
Player = 1
}
agent h = CreateUnit(Player(0),'hfoo',0,0,0);
gets translated to::
agent h = CreateUnit(0(0),'hfoo',0,0,0);
I thought it would require using . notation like C#/C++, but in fact Agent.Player returns Agent.0
ADOLF resisted implementing enum_name.enum_value notation, it's just enum_name for now :/ I'd like to have it like in C++, <s>but he's against doing it.</s> and he agreed to implement it =)
So this is just partially a bug as enum values are not yet implemented (now it's 0,1,2,...), but they will be.
VD

posted at 13/09/09 04:13
weaaddar

Adolf certainly, but in C languages the following statement is ambiguous::
i++==i++
It might be true, or it might be false you never know.
I completely understand that this can be quiet difficult. I've actually toyed with a Lambda calculus compiler for scheme. So we all have our own quirks.
Fantastic about textmacros that actually understand what the syntax they parse means. This project has amazing velocity, and I really look forward to your latest work. I'm almost toying with a notion to implementing a syntactic sugar language atop of vJass but I'm not sure of its need at this rate :)

posted at 12/09/09 22:02
ADOLF

This post will be the answer to almost all questions, asked in the latest posts.
At first, I'd like to note than not everything is as simple, as you imagine =)
It's very possible that I'll implement local variables for increments/decrements in cases like postfix operations in if/return or prefix in elseif (but problems with more than one increment of the same variable in the return/if/elseif expression will still be present). Moreover, I'll implement variables when incrementing arrays with functions as index, eg:
<span class="code">i[GetRandomInt(0,1)]++</span>, that should become something like: <div class="code">temp = GetRandomInt(0,1)
i[temp]=i[temp]+1</div>
But I can't say for certain when I'll do that cause now there are some critical issues that require my attention. Now one of them is implementing native textmacro processing to avoid errors when compiling vjass maps, that use them heavily.
I'll also implement local variables for different scopes as it's necessary to add "for" loop, which is also in my to-do list.
As for assembler, well, my main job isn't related to IT at all, so programming is my hobby, it's somehow like a puzzle. Asm is not a programming language, it's more like a religion - very beautiful and elegant. I may be crazy, but this is my own way...
And thanks to VD for translating all this =]

posted at 12/09/09 20:02
Dark Dragon

yeah i know what u mean but well if ADOLF wants to implement that:
if (unit u = GetTrig...)
it will be good but i was only trying to say that i belive this might be problematic to add and so...

posted at 12/09/09 19:56
weaaddar

It'll still be fast, but it leads to problematic code if you do it the lazy way.
this[.Size++] = value
Should really translate to:
int tempVar = .Size
.Size= .Size+1
this[tempVar]
Right now, you have to know the incorrect behavior, and code around it
this[++.Size-1]. In fact, I'd really perfer that cJass always uses the above definition. This should never lead to conflict, but will cost another integer/float subtraction which should be a microscopic cost in the grand scheme of things.
As for doing that assignment it really wouldn't be so bad if we got scope safe variable declaration. Even if all that is doing is just changing vars name. Disallow shadowing if you must (and I'd perfer it as its pretty unsafe).
if(GetTriggerUnit() !=null)
{
unit foo = GetTriggerUnit();
// some code here
}
foo = null; //this should be a compile error.
could easily translate to::
local unit S1__foo
if(GetTriggerUnit() != null)
{
unit S1__foo = GetTriggerUnit()
}
foo = null//error! as foo isn't declared.
And then its a trivial amtter of extending scope to ifs and whilenot blocks.

posted at 12/09/09 18:09
Dark Dragon

@ weaaddar
reason why i like c++ the most is coz of how easy its to write the code and how fast that code is. function pointers in vjass are one of my fav features but are slow and code generated is bad coz of triggers and all that. i like structs as well a lot.
all features cjass adds are of top speed and code is quickly written and easy to read.
i am as well fun of c++ so this is really awesome work for me.
if (unit u = null == null) {}
maybe might be added but for checks i dont think so... coz you know that this var must be put at top of func
cJass is still limited on jass and i know you said you dont care how its compiled to jass but i am different coz jass is basically what matters... especially for wc modes like my one where top speed is requied.

posted at 12/09/09 07:09
weaaddar

I can understand for a fear of complexity, but truthfully as long as it works as expected under the covers then who cares about the Jass generated.
Anyway for my other point I think it really falls to extension methods. Which are certainly just type-safe hooks. Here was my proposed notation from the jasshelper thread::
Static Struct UnitUtils
{
void operator .X=(this unit u, real value)
{
SetUnitX(u,value);
}
real operator .X(this unit u)
{
return GetUnitX(u);
}
}
Okay, another question will cJass support assignment in if/whiles?
i.e.
if(unit u = GetTriggerUnit() !=null)
{
printf("Called by a triggered method involving unit"+GetHandleId(u))
}
else
{
printf("Not called by a triggered method!")
}
And for variable scope! I absolutely love being able to declare variables anywhere, but I'd like that my variables have scope even if it is artificially generated. (This might fall in to that I'm a crazy guy that likes my compiled jass to look ugly).
i.e.
void test()
{
x = 6; // throw an error, x is not defined!
if(SomeCondition)
{
int x = 5;
}
x+=7; //should throw a compile error as x in scope
}
Again though don't take any of this as criticism as I love your work, and Adolf man you are nuts, who intentionally works in ASM? Your stomp map brought me back to flashbacks of working on a calculator...

posted at 11/09/09 14:40
Dark Dragon

k few things now about cJass local moving...
[jass]
void test() {
if (true) {int i = 5; IMsg(i)}
else {int i = 7; IMsg(i)}
}
[/jass]
its not of top priority to fix but well would be nice since i really like cJass way of making code simple! basically you can fix that by checking for only first local and move it on the top, then at all declared places you remove that "int" and its done...
so compiled should look like!
[jass]
void test() {
int i // no value set, we just declare it once
if (true) {/int/ i = 5; IMsg(i)}
else {/int/ i = 7; IMsg(i)}
}
[/jass]
thats how i think would be cool :)
now as well i would like to know how to use undef and how bacially does cJass know after which line should it be undeclared...
mybe like this?
[jass]
void local_def() {
define s = "Hello World!"
Msg(s)
undef s
}
[/jass]
now thats an local define? or simply local constant string s xD
really not sure but i guess its smth like that!
Greets!
~DD

posted at 11/09/09 14:40
MasterofRa

A problem that prevents me from using cJass is that it creates compile errors when I use textmacros anywhere with the syntax checker on

posted at 10/09/09 16:41
weaaddar

I understand we can't access low level memory, but how hard could it be to generate a variable with a guid name?
Anyway, fantastic news about the templates. Does that mean the compiler will start understanding types? Could I potentially then hook by type?
i.e.
define <unit u><.X=>val = SetUnitX(x,val)
define <item u><.X>val = SetItemX(x,val)
The goal of cJass is to simplify the code and at the same time not make it more complex, so your proposal with variable for ++ was declined. ADOLF, anyway, will implement a fix for that return i++ behavior.
Templates are not yet in development cycle and I don't know how or when they will be implemented.
For now, no type understanding is implemented and not sure about that :( And I don't know if such way of using defines will ever be possible.
VD

posted at 10/09/09 15:16
Dark Dragon

i am glade it helped, but i just realized i did smth wrong! for example:
int tst(int a) {return a++ / 5}
well now it would bug in my old example, so ADOLF should use brackets like this:
int tst(int a) {return (++a-1) / 5}
i just forgot about that and wrote + example but when it comes with bigger priority operator then it would bug :S
just wanted to point this out, anyway greets guys!
~DD
Yeah, ofc in brackets =)
VD

posted at 10/09/09 14:45
Dark Dragon

about return i++ bug i just suggest ADOLF to detect is i++ used in return and if it is then change that to:
int tst(int a) {return a++ + 5}
should be:
int tst(int a) {return ++a-1 + 5}
and thats all simply fixed :]
ADOLF said that's a great idea and he'll do so. Thanks =)
VD

posted at 10/09/09 07:07
weaaddar

As for i++ as far as I understand what C generally compiles that statement down to is::
incrementor(int ref i)
{
j = i;
i = i+1;
return j;
}
in psuedo code. I.e. i++ returns a copy of i before incrementation. [Stored in registers or whatever so its ultrafast but thats not the point].
The simple solution is that using i++ declares another local variable to hold the i++ value before the increment.
e.g.
int I;
int increment()
{
return I++;
}
Should translate to::
int I
function increment takes nothing returns integer
local integer UNIQUENAMEHERE = I
set I = I + 1
return UNIQUENAMEHERE
endfunction
where uniquenamehere is some unique variable name that cjass generates on the fly.
Seriously, treat Jass like assembler, as after using cJass's ease it really feels like it :P
Yeah, I've just checked the C compiler logic with debugger and you're almost right: it first stores the previous value in some memory area and then takes the value again, increases it and stores to other memory area.
Unfortunately, we don't have low-level memory access in JASS, that's why we translate i++ the way it is (i;i = i + 1) not to complicate the code.
Anyway, we'll think what we can do with return i++ logical flaw in the future versions. I can't promice it will be fixed, but we'll definitely think about it =)
VD

posted at 10/09/09 05:33
weaaddar

It seems the bug is fixed that caused the defines to freak about {}s.
However, I'm having a bit of a difficulty assigning aliasing to my parametric types.
So I'd like to be able to go:
List(int) myList = new List(int)(10);
// instantiate a list of type int, that can hold 10 elements.
But I can't figure out how to write the define::
define new list(T)(x) = list(T).create(x) doesn't seem to work.
The lame version is define new List(T,x) which does work but seems odd.
Yeah, it was some lame bug, that seemed to appear and disappear occasionally for no particular reason.
We've already discussed templates with ADOLF and it seems they are not very hard to implement. And after they are here, you'll be able to write smth like
<div class="code"><b>template</b>&lt;T&gt; {
&nbsp;&nbsp;<b>struct</b> List&lt;T&gt; {
&nbsp;&nbsp;&nbsp;&nbsp;hashtable w_List&lt;T&gt; = InitHashtable()
&nbsp;&nbsp;&nbsp;&nbsp;...
&nbsp;&nbsp;}
}
List&lt;int&gt; mylist;</div>or even<div class="code"><b>template</b>&lt;T&gt; {
&nbsp;&nbsp;<b>define</b> &lt;new List&lt;T&gt;&gt;(x) = List&lt;T&gt;.create(x)
}</div>Not quite sure about defines in templates, but who knows =)
VD

posted at 10/09/09 03:06
Dark Dragon

i see, well it will be good if it gets fixed but i can live with it as is now.
about function pointers! i would most likely like that C-style its crazy to write function interface blah takes real x, real y returns real
just do this would be simple and readable:
float min(float x, float y) {...}
void main() {
float pf(float, float) = min
float f = pf.evaluate(2, 3)
}
k i would like that .evaluate is default called so i dont need to write it but if its hard for ADOLF then i can live with that but func inter... bla bla is so boring :S
but as you said you still seek for an good syntax so i just give my example ;)
about that answer with values and consts!
i can say only thanks for ur hard work and time u spent on to explain all this, its awesome and i get it. so once again thanks for the answer :)
Greets!
~DD

posted at 10/09/09 00:56
Van Damm

@ Dark Dragon
And now about constants and values
<a name="constants-vs-values"></a>Here's the JASS code, which we're going to disassemble:
<div class="code">constant real x = 0.
define xx = 0.
void fx () { real const = x, def = xx }
</div>
And here's what operations we've got when the above code is run by the game's JASS interpreter:
<div class="code">08C9E0A0 fx+0000 00 00 05 05 00000eaf &nbsp;&nbsp;&nbsp; CREATE_LOCAL const {real (5)}
08C9E0A8 fx+0008 00 05 68 0e 0000024a &nbsp;&nbsp;&nbsp; <b>MOV_VAR_REG x => #68 {real (5)}</b>
08C9E0B0 fx+0010 00 00 68 11 00000eaf &nbsp;&nbsp;&nbsp; MOV_REG_VAR #68 => const
08C9E0B8 fx+0018 00 00 05 05 00000eb0 &nbsp;&nbsp;&nbsp; CREATE_LOCAL def {real (5)}
08C9E0C0 fx+0020 00 05 69 0c 00000000 &nbsp;&nbsp;&nbsp; <b>MOV_VAL_REG 0 => #69 {real (5)}</b>
08C9E0C8 fx+0028 00 00 69 11 00000eb0 &nbsp;&nbsp;&nbsp; MOV_REG_VAR #69 => def
08C9E0D0 fx+0030 00 00 00 27 00000000 &nbsp;&nbsp;&nbsp; RETURN
08C9E0D8 fx+0038 00 00 00 04 00000000 &nbsp;&nbsp;&nbsp; STUB_FUNC_END
</div>
As you see, on line 2 the value is taken from the memory area, corresponding with the constant address and placed to the register (it's in bold text). Then the value in the register assigned to the local variable at line 3.
On line 5, direct value is placed to the register (it's in bold text), and then assigned to the second local variable at line 6.
If to make an example in plain asm, the difference is the same as the difference between these two statements:
<div class="code">mov eax, dword ptr [40000000h] <i>; address</i>
mov eax, 10h &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;​&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i>; value</i>
</div>
In the first case, you have to look the memory for the address, then find what value is in that memory area and then move the value to the register.
In the second case, you just move the value to the register - it's much faster.
That's why in cJass defines do direct value substitution.

posted at 09/09/09 20:01
Dark Dragon

in mean time while using cJass i now descoverd an logical bug... its not an bug ADOLF wanted that it works that way but its wrong...
example:
integer Int = 0
integer ActionsWithPP() { return Int++ }
will be ofc:
integer ActionsWithPP() { return Int; Int++ }
where it should be:
integer ActionsWithPP() { Int++; return Int-1 }
and i need exactly Int++ not ++Int, just want to let you know that i know about ++Int ;)
ofc i can do ++Int-1 but it is lesser readable and looks bad :S
ohh and in mean time did ADOLF add &func or smth so that we dont any more write function func... yeah sry for all this boring questions but i really hate that syntax since everything is now c++ like except that pointer functions stuff and function interface blabla takes ...
anyway greets ;)
~DD
Yeah, we know about that logical flaw, but I don't know if or when it will be fixed.
As for function interfaces, I didn't come to any reasonable way to write it in C-style and leave easily understandable. Function pointers are not yet here, but I'll add them to out to-do list =)
VD

posted at 09/09/09 16:09
Dark Dragon

thanks a lot VD ;)
its really not ofc that script would improve if i would use one thats faster but its just that i want to know :)
once again, thanks!
~DD

posted at 09/09/09 14:53
Dark Dragon

Hi ADOLF and Van Damm!
well i was just checking a bit anti-bj.j
and i have an question!
i saw that for example bj_PI is now calling value instead of constant...
so i was wondering whats actualy faster value or constant which is already in memory? i always thought that constants are faster then values, for example bj_DEGTORAD is 0.01745... not bj_PI/180.
at school my teacher said that computer reads variables from memory really fast... so yeah correct me if i am wrong.
Thanks and sry for this question its not like it has to do many things with cJass but its about "anti-bjs" ^^
Greets!
~DD
I think that's a question to adolf cause he knows a lot more about memory organization and so =) I'll ask him.
VD

posted at 09/09/09 14:08
Dark Dragon

@ weaaddar
before testing it, you should know that you have bug in your code!
you wrote "ThenCode" in your define but argument is "TrueCode"
overall FalseCode should work...
as well try to call that define like this:
ite(true,<BJDebugMsg("True")>,<BJDebugMsg("False")>);
see if it works, did not test it but might work, as well dont forget to change ThenCode and TrueCode
It's ok, I've tested it with correct code and it isn't working if there are more code in the map :( I'm trying to find out what's causing the mess.
VD

posted at 09/09/09 05:43
Strilanc

Bug in the anti-bj pack:
The BJ trig functions take degrees instead of radians. You need to multiply the inputs and outputs to correct the difference.
I'll see what I can do
VD

posted at 09/09/09 05:24
weaaddar

There seems to be a serious issue with using the Define and {}s.
Consider the following:
define ite(cond,TrueCode,FalseCode) =
{
if(cond)
{
ThenCode
}
else
{
FalseCode
}
}
void test()
{
ite(true,BJDebugMsg("True"),BJDebugMsg("False"));
}
Which generates as::
function test takes nothing returns
nothing
if ( true ) then
ThenCode
else
FalseCode
endif
endfunction
function test takes nothing returns
nothing
Instead of the expected:
if(true) then
call BJDebugMsg("True")
else
call BJDebugMsg("False")
endif
endfunction
Since I'd like to generate templated classes using cJass this is quiet a problem for me.
Yeah, I see. I'm trying to find out why it's failing
VD

Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [21] 22 23 24 25 26 27

[back to top]