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”.

12: assembly VOL I