Free Hero Mesh

Check-in [939a14c642]
Login
This is a mirror of the main repository for Free Hero Mesh. New tickets and changes will not be accepted at this mirror.
Overview
Comment:Implement and document user-defined function calls. Also document the goto and gosub operators.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 939a14c642de8f037fadd5d558d179a6a282b090
User & Date: user on 2021-03-03 00:45:36
Other Links: manifest | tags
Context
2021-03-03
07:36
Add a file describing what files make up a puzzle set. check-in: a56f5e603a user: user tags: trunk
00:45
Implement and document user-defined function calls. Also document the goto and gosub operators. check-in: 939a14c642 user: user tags: trunk
2021-03-02
23:07
Fix another mistake in saving levels check-in: 5a0f5f4cb4 user: user tags: trunk
Changes

Modified class.doc from [20b90f2037] to [52e75cc8f5].

39
40
41
42
43
44
45

46
47
48
49
50
51
52
  $  Class
  @  Global variable
  '  Key code
  :  Label
  %  Local variable
  #  User message
  !  User sound


Comments are also allowed; these start with a semicolon (outside of a
string literal) and end at the next line break.


=== Escapes ===








>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  $  Class
  @  Global variable
  '  Key code
  :  Label
  %  Local variable
  #  User message
  !  User sound
  &  User function

Comments are also allowed; these start with a semicolon (outside of a
string literal) and end at the next line break.


=== Escapes ===

218
219
220
221
222
223
224
225

226
227
228
229
230






231
232
233
234
235
236
237
(@<name> <value>)
  Define a global variable and its initial value.

(@<name> Array <rows> <columns>)
  Define a global variable whose value is a reference to a new array, with
  the specified dimensions. The maximum number of rows is 64, and the
  maximum number of columns is 1024, and the maximum number of cells in
  all arrays in total is 65534.


(<message> <code...>)
  Defines a default message code for all classes which do not specify
  their own code for this message.








=== Class definitions ===

Within a class definition, the following definitions can be used. See also
the section about variables; many of these definitions are used to specify
the initial value for variables of objects of this class.








|
>





>
>
>
>
>
>







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
(@<name> <value>)
  Define a global variable and its initial value.

(@<name> Array <rows> <columns>)
  Define a global variable whose value is a reference to a new array, with
  the specified dimensions. The maximum number of rows is 64, and the
  maximum number of columns is 1024, and the maximum number of cells in
  all arrays in total is 65534. All elements are initialized to zero when
  the level starts.

(<message> <code...>)
  Defines a default message code for all classes which do not specify
  their own code for this message.

(&<name> <code...>)
  Define a user-defined function. User-defined functions may take any
  number of inputs from the stack and leave any number of outputs on the
  stack, but may not access user-defined local variables. (It may still
  access standard local variables, and all global variables, though.)


=== Class definitions ===

Within a class definition, the following definitions can be used. See also
the section about variables; many of these definitions are used to specify
the initial value for variables of objects of this class.

907
908
909
910
911
912
913














914
915
916
917
918
919
920

Some instructions are block instructions; see the next section.

Many instructions are state-changing instructions; these instructions are
marked with ** in the summary line. Such instructions are not allowed to be
used on the same turn as the IgnoreKey instruction.















.  ( x -- )

+  ( in1 in2 -- out )
  Add two numbers together.

-  ( in1 in2 -- out )
  Subtract in2 from in1.







>
>
>
>
>
>
>
>
>
>
>
>
>
>







915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942

Some instructions are block instructions; see the next section.

Many instructions are state-changing instructions; these instructions are
marked with ** in the summary line. Such instructions are not allowed to be
used on the same turn as the IgnoreKey instruction.

<label>
  Define a label. Labels are local to the current class. (Label names
  always start with a colon.)

=<label>
  Go to a label. (Put the colon after the equal sign; this instruction,
  and the one below, are using a double sigil.)

,<label>
  Call a label as a subroutine; when it returns, comes back to here.

<function>
  Call a user-defined function.

.  ( x -- )

+  ( in1 in2 -- out )
  Add two numbers together.

-  ( in1 in2 -- out )
  Subtract in2 from in1.

Modified exec.c from [17ab5f4c5c] to [b7234aa702].

1440
1441
1442
1443
1444
1445
1446

1447
1448
1449
1450
1451
1452
1453
    case OP_DUP: StackReq(1,2); t1=Pop(); Push(t1); Push(t1); break;
    case OP_EQ: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t2)?1:0)); break;
    case OP_FLUSHCLASS: NoIgnore(); StackReq(1,0); t1=Pop(); if(t1.t==TY_CLASS) flush_class(t1.u); else if(t1.t==TY_NUMBER && t1.s==-1) flush_all(); else if(t1.t) Throw("Type mismatch"); break;
    case OP_FLUSHOBJ: NoIgnore(); flush_object(obj); break;
    case OP_FLUSHOBJ_C: NoIgnore(); StackReq(1,0); i=v_object(Pop()); if(i!=VOIDLINK) flush_object(i); break;
    case OP_FOR: NoIgnore(); StackReq(3,1); t3=Pop(); t2=Pop(); t1=Pop(); ptr=v_for(code,ptr,t1,t2,t3); break;
    case OP_FROM: StackReq(0,1); Push(OVALUE(msgvars.from)); break;

    case OP_GE: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t2,t1)?0:1)); break;
    case OP_GE_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t2,t1)?0:1)); break;
    case OP_GETARRAY: StackReq(3,1); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); t1=Pop(); Push(v_get_array(t1,t2.u,t3.u)); break;
    case OP_GETINVENTORY: StackReq(2,2); t2=Pop(); t1=Pop(); v_get_inventory(t1,t2); break;
    case OP_GOTO: ptr=code[ptr]; break;
    case OP_GT: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t1,t2)?1:0)); break;
    case OP_GT_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t1,t2)?1:0)); break;







>







1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
    case OP_DUP: StackReq(1,2); t1=Pop(); Push(t1); Push(t1); break;
    case OP_EQ: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t2)?1:0)); break;
    case OP_FLUSHCLASS: NoIgnore(); StackReq(1,0); t1=Pop(); if(t1.t==TY_CLASS) flush_class(t1.u); else if(t1.t==TY_NUMBER && t1.s==-1) flush_all(); else if(t1.t) Throw("Type mismatch"); break;
    case OP_FLUSHOBJ: NoIgnore(); flush_object(obj); break;
    case OP_FLUSHOBJ_C: NoIgnore(); StackReq(1,0); i=v_object(Pop()); if(i!=VOIDLINK) flush_object(i); break;
    case OP_FOR: NoIgnore(); StackReq(3,1); t3=Pop(); t2=Pop(); t1=Pop(); ptr=v_for(code,ptr,t1,t2,t3); break;
    case OP_FROM: StackReq(0,1); Push(OVALUE(msgvars.from)); break;
    case OP_FUNCTION: execute_program(classes[0]->codes,functions[code[ptr++]],obj); break;
    case OP_GE: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t2,t1)?0:1)); break;
    case OP_GE_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t2,t1)?0:1)); break;
    case OP_GETARRAY: StackReq(3,1); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); t1=Pop(); Push(v_get_array(t1,t2.u,t3.u)); break;
    case OP_GETINVENTORY: StackReq(2,2); t2=Pop(); t1=Pop(); v_get_inventory(t1,t2); break;
    case OP_GOTO: ptr=code[ptr]; break;
    case OP_GT: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t1,t2)?1:0)); break;
    case OP_GT_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t1,t2)?1:0)); break;