MitchBradley/cforth

Getting parameters in right order for C API

Closed this issue · 7 comments

my C API is full of calls like this:
position(obj, x, y);
size(obj, w, h);
set_mode(obj, mode, const1, const2);
align(obj, const1, const2, const3);

So for the align call
(obj --)
const3
const2
const1
3
pick
align

I'm trying to avoid variables since they are global and I don't want namespace collisions between the different snippets. Is pick the right way to keep bringing obj up to top of stack? If I don't use pick the needed dup/swap/rot get pretty confusing. Is the pick implementation fast?

Pick is fine.

/*$p pick */ case PICK: tos = sp[tos]; next; which compiles to one machine instruction on a most architectures, above the basic threaded code overhead that applies to every Forth primitive.

I just noticed local variables, since I am doing this over and over, storing 'obj' in a local variable would be easier to understand.

Locals are fine too. The other paradigm is to put obj on the return stack:

: foo  ( n2 n1 n0 obj -- )
    >r            ( n2 n1 n0 r: obj )
    r@ blah   ( n2 n1 r: obj ) \ do something with n0 under obj
    r@ foo     ( n2 r: obj ) \ do something with n1 under obj
    r> bar      ( )  \ do something with n2 under obj while removing obj from the return stack
;

In your align case it would be

: myalign  ( obj -- )
   >r  const3 const2 const1 r> align
;

What is syntax for locals in your forth? there seems to be many variations in the various forth implementations.
Do I need to declare them all up front?
Stack initialized?
Uninitialized?
Does ! and @ work with them?

This looks fairly readable to me....

string-array rooms ," Master Bedroom" ," Living Room" ," Office" ," Kitchen" 
    ," Backyard" ," Garage" ," Dining Room" ," Front Door" 
end-string-array

0 addr_scr_event_cb lv-scr-act lv-obj-add-event-cb drop 

: create_button ( y x -- button)
lv-scr-act lv-btn-create
>r 
r@ lv-obj-set-pos
73 92 r@ lv-obj-set-size
0 addr_btn_event_cb r@ lv-obj-add-event-cb drop
r> ;

: apply_label ( index button -- )
lv-label-create ( button -- label )
>r 
0 r@ lv-label-set-long-mode 
rooms count @r lv-label-set-text
80 r@ lv-obj-set-width
0 0 9 r@ lv-obj-align
r> lv-obj-center ;

: make_coordinates 97 * 25 + swap 78 * 5 + swap ;  ( row col -- y x)

: make_index swap 2 * + ; ( row col -- index )

: do_button ( row col -- )
2dup
make_index
rot rot
make_coordinates 
create_button ( y x -- button)
apply_label ( index button -- ) ;

: loop_col 2 0 do i do_button  loop ; ( row -- )
: loop_row 4 0 do i loop_col loop ; ( -- )
loop_row

locals.fth has several syntax alternatives for locals, with examples showing how to use them. I prefer the Bradley Forthware syntax, not surprisingly since I am that Bradley.

: .squared { n ; m -- }  \ n is set from the stack, m is an uninitialized local
  n n * to m
  m .
;