L1VM - course 11
L1VM - preprocessor
Here I will show how to use the L1VM preprocessor to include headers and defining macros.
To include the “intr.l1h” interrupt macro header we use:
#include <intr.l1h>
This must be included at the top of a program before the main function. Note: the modules includes are included at the bottom of a program.
There are three types of preprocessor macros:
#define
#func
#var
With “#define” we can set a replacement text for a macro. Here is an example out of “intr.l1h” (this shows the stack pointer):
#define show_st_p (14 0 0 0 intr0)
The preprocessor replaces every text with “show_st_p” by the text “(14 0 0 0 intr0)”. So you can write the macro name in your program without need to know the interrupt “0” number “14”!
The “#func” macro defines a function with variables that can be used to call the function:
#func get_time (THOUR, TMIN, TSEC) :(17 THOUR TMIN TSEC intr0)
This is the “get_time” macro it has three arguments: “THOUR”, “TMIN”, and “TSEC”.
The replacement part begins after the “:” char. Here the macro variables are inserted into: “(17 THOUR TMIN TSEC intr0)”.
The macro can be called with something like this:
get_time (hour, min, sec)
The three variables can be of type int for example.
Here is a more advanced function:
#func inside_coord (MX, MY, X, Y, X2, Y2) :{f~ = ((MX > X) && (MX < X2)) && ((MY > Y) && (MY < Y2))}
To use this you just do:
inside_coord (mx, my, x, y, x2, y2)
Here “mx/my” is the coordinate to check. If the two coordinate variables “mx” and “my” are in the range of “x”, “x2” and “y”, “y2” then the variable “f~” is set to one. So “f~” can be checked with an “if”.
Here is a full example:
// coord-xy.l1com
// preprocessor function demo
//
#include <intr.l1h>
#func inside_coord (MX, MY, X, Y, X2, Y2) :{f~ = ((MX > X) && (MX < X2)) && ((MY > Y) && (MY < Y2))}
(main func)
(set int64 1 zero 0)
(set int64 1 one 1)
(set int64 1 x 100)
(set int64 1 x2 200)
(set int64 1 y 50)
(set int64 1 y2 100)
(set int64 1 mx 110)
(set int64 1 my 60)
(set int64 1 f~ 0)
(set string s insidestr "m position inside!")
(set string s outsidestr "m position outside!")
inside_coord (mx, my, x, y, x2, y2)
(f~ if+)
print_s (insidestr)
print_n
(else)
print_s (outsidestr)
print_n
(endif)
exit (zero)
(funcend)
The “#var” macro defines the function name ending on variables. Here is a function taken from my “pov-edit” POV editor:
(init_paint_rect func)
#var ~ draw_paint_rect
(set const-int64 1 zero~ 0)
(set const-int64 1 one~ 1)
(set int64 1 x_start~ 10)
(set int64 1 y_start~ 10)
(set const-int64 1 x_width~ 50)
(set const-int64 1 y_height~ 8)
(set const-int64 1 tile_width~ 18)
(set int64 1 x_tiles~ 0)
(set int64 1 y_tiles~ 0)
(set byte 1 color~ 0)
(set byte 1 alpha~ 255)
(zero~ zero~ x_start~ y_start~ x_width~ y_height~ tile_width~ tile_width~ color~ color~ color~ alpha~ one~ :set_gadget_box_grid call)
(funcend)
So here “#var ~ draw_paint_rect” sets the variable name ending to “draw_paint_rect”. So the variable “zero~” will be expanded to “zerodraw_paint_rect”.