sannybuilder/dev

Feature: Function/Pointer syntax

Opened this issue · 5 comments

XMDS commented

In fact, it may not make sense to do so. But in theory, I hope that the sb tool can add more new OP writing methods. Essentially, I think we should add a new simple syntax to the frequently used basic OP and SA (CLEO4).VC.3 (CLEO2.0) OP

In fact, I got the idea from gosub:
gosub @xxxx
xxxx ()

But actually you should add highlighting to the above code

Back to the topic, I have an example:
0AA5: call 0x123456 num_params 3 pop 3 0@ 1@ 2@
Maybe this:
call 0x123456 (3 2@ 1@ 0@)
call 0x123456 3(2@ 1@ 0@)
By writing call address + (parameter), the SB tool can automatically detect the number of parameters (num_params) in () when compiling.
In fact (3 2@ 1@ 0@), the 3 in () should be the pop parameter. In fact, OP 0AA5 fills the parameters in CLEO upside down, which is very uncomfortable. 2@ should be the first parameter

More examples:
0AA5: call 0x123456 num_params 3 pop 3 0@ 1@ 2@
call 0x123456 (3 2@ 1@ 0@)

0AA6: call_method 0x123456 struct 30@ num_params 3 pop 3 0@ 1@ 2@
call 0x123456 30@(3 2@ 1@ 0@)

0AA7: call_function 0x123456 num_params 3 pop 3 0@ 1@ 2@ ret 3@
call 0x123456 (3 2@ 1@ 0@) ret 3@

0AA8: call_function_method 0x123456 struct 30@ num_params 3 pop 3 0@ 1@ 2@ ret 3@
call 0x123456 30@(3 2@ 1@ 0@) ret 3@

0AB1: call_scm_func @xxxx 3 0@ 1@ 2@ ret 3@ 4@ 5@
call xxxx (3 0@ 1@ 2@)ret 3@ 4@ 5@
:xxxx
0AB2: ret 3 3@ 4@ 5@
ret (3@ 4@ 5@)
ret 0 = ret

Just like the example, the sb tool automatically detects the number of parameters (). But the above code is still not good. Such as pop and struct parameters. Maybe it can be declared at the beginning:
var
this 30@
stdcall 0x654321
cdecl 0x123456
end

call 0x123456 (30@ 2@ 1@ 0@}
call 0x654321 (30@ 2@ 1@ 0@}

In the end I suggest this
call address + (parameter)
pop and struct can be declared at the beginning

XMDS commented

Or like this

var
 this 30@
end

0AA5: call 0x123456 num_params 3 pop 3 0@ 1@ 2@
0AA5: call 0x123456 num_params 3 pop 0 0@ 1@ 2@
_cdecl call 0x123456 (2@ 1@ 0@)
_stdcall call 0x123456 (2@ 1@ 0@) 

0AA6: call_method 0x123456 struct 30@ num_params 3 pop 3 0@ 1@ 2@
0AA6: call_method 0x123456 struct 30@ num_params 3 pop 0 0@ 1@ 2@
_cdecl call 0x123456 (30@ 2@ 1@ 0@)
_stdcall call 0x123456 (30@ 2@ 1@ 0@)

0AA7: call_function 0x123456 num_params 3 pop 3 0@ 1@ 2@ ret 3@
0AA7: call_function 0x123456 num_params 3 pop 0 0@ 1@ 2@ ret 3@
_cdecl call 0x123456 (2@ 1@ 0@) 3@
_stdcall call 0x123456 (2@ 1@ 0@) 3@ 

0AA8: call_function_method 0x123456 struct 30@ num_params 3 pop 3 0@ 1@ 2@ ret 3@
0AA8: call_function_method 0x123456 struct 30@ num_params 3 pop 0 0@ 1@ 2@ ret 3@
_cdecl call 0x123456 (30@ 2@ 1@ 0@) 3@ 
_stdcall call 0x123456 (30@ 2@ 1@ 0@) 3@

0AB1: call_scm_func @xxxx 3 0@ 1@ 2@ ret 3@ 4@ 5@
_scm call xxxx (0@ 1@ 2@) 3@ 4@ 5@

:xxxx 
0AB2: ret 3 3@ 4@ 5@
ret  (3@ 4@ 5@)
x87 commented

@XMDS thanks for the feedback.

But actually you should add highlighting to the above code

IDE should highlight a callable label:
sb-call-highlight

Does that work for you?

Regarding functions. Yes I want to expand on functions syntax more. Gosubs were just an easy change and I want to implement a similar syntax for SCM functions and call opcodes.

You don't have to specify calling convention (stdcall/cdecl) each time you call a function. Basically I would introduce a new syntax for functions declaration where you can tell the compiler how many arguments it takes and other information. Something like:

declare external function my_function at 0x123456 params 3 stdcall

then

my_function(0@,1@,2@) // 0AA5: call 0x123456 num_params 3 pop 0 2@ 1@ 0@

or

30@.my_function(0@,1@,2@) // 0AA6: call_method 0x123456 struct 30@ num_params 3 pop 0 2@ 1@ 0@

or

(3@,4@,5@) = my_function(0@,1@,2@) // 0AA7: call_function 0x123456 num_params 3 pop 0 2@ 1@ 0@ ret 3@ 4@ 5@

or

(3@,4@,5@) = 30@.my_function(0@,1@,2@) // 0AA8: call_function_method 0x123456 struct 30@ num_params 3 pop 0 2@ 1@ 0@ ret 3@ 4@ 5@

changing stdcall to cdecl would change the resulting pop value to 3

still not sure about multiple returning values syntax, but this is a draft.

XMDS commented

@x87
Regarding the command to get the pointer, we have a discussion here:
#136

Should it be like the function syntax, instead of using the class form, but using the independent form, for example:

0AC7: 1@ = var 0@ pointer
1@ = 0@*

0AC6: 0@ = label @label pointer
0@ = @label*

0A9F: 0@ = get_this_script_struct
0@ = Script*

0AAA: 0@ = get_script_struct_named 'xxx'
0@ = Script* 'xxx'

Can be declared for people, cars, and obj pointers:

0A96: 0@ = ped $PLAYER_ACTOR struct
0A97: $CarStruct = vehicle $MyCar struct
0A98: $ObjectStruct = object 0@ struct
Var
  0@ : char
 1@ : Car
 2@ : Object
 3@s: Script
end

0@ = 0@*
1@ = 1@*
2@ = 2@*
3@ = 3@s* //3@ = Script* 'xxx'

Should also support const……end instruction to define pointer writing of variable names. The above are all my personal suggestions. If there is a better grammar, I can discuss it

x87 commented

* can be confused with multiplication, hence it's ambiguous.

My proposal would be a syntax similar to Rust - adding & in front of the variable returns its address. So:

0AC7: 1@ = var 0@ pointer
1@ = &0@

0AC6: 0@ = label @label pointer
0@ = &@label

this won't have collisions with ADMA syntax as ADMA variables are always numeric.

for entities:

0A96: 0@ = ped $PLAYER_ACTOR struct
0A97: $CarStruct = vehicle $MyCar struct
0A98: $ObjectStruct = object 0@ struct
Var
  0@ : char
 1@ : Car
 2@ : Object
 3@s: Script
end

0@ = &0@ // however it's not clear whether we want variable pointer or entity pointer, maybe needs a dereference operator like: 0@ = &*0@
1@ = &1@
2@ = &2@

not sure about syntax for the script pointer. maybe leave it as a keyword:

0@ = get_this_script_struct
0@ = get_script_struct_named 'xxx'

XMDS commented

* can be confused with multiplication, hence it's ambiguous.

My proposal would be a syntax similar to Rust - adding & in front of the variable returns its address.

I very much agree, because I also thought of using * or &, indeed the latter is better