Introduction

This is a very brief description of the Zomic language.  Zomic is designed to allow the concise description of vZome model constructions.

This reference is organized around a formal grammar for Zomic, with brief but complete descriptions of each language feature.  First, however, it is best to understand the execution model for Zomic, describe in the next section.

Virtual Machine

The Zomic virtual machine (or "VM" for short) operates on a virtual Zome model (a collection of struts and connector balls), and effects changes to the model through strut-building statements.  The action of these strut statements is adjusted according to four state variables in the VM:

	location		A position in the virtual Zome space.  There may or may not be a connector ball in the model at that location.  A strut statement always starts at the current location, and sets the location to the end of the new strut.  The initial location is the origin, (0,0,0).

orientation		A linear mapping of the Zome axes.  Mathematically, this can be treated as the composition of a rotation around one of the 31 axes, and possibly a mirror reflection through one of the axes.  Either or both may be the identity mapping, of course.  The orientation mapping is applied to the axis of any strut statement before that statement is executed on the model.  The initial orientation is the identity mapping.

scale			A "magnification" to be applied to strut sizes, which are simply integer values.  The scale variable is added to the size of each strut.  The resulting value is used as the exponent for Tau in computing the length of the strut to build.  The initial scale is zero.

build mode		A "switch" that can be on or off.  When on, strut statements cause struts (and usually connector balls) to be added to the model.  When off, strut statements have no effect on the model, but the location variable is still affected.  Build mode is on by default.

Zomic Grammar

The grammar is shown in Courier font.  Grammar nonterminal symbols are shown in italics.  Keywords and literals are in 'bold'.  Parentheses indicate grouping, "?" indicates an optional element, "+" indicates one-or-more repetitions, and "|" separates choices.

The following tokens are used throughout the grammar:

DIGIT : '0'..'9'

INT : DIGIT+

SIGNED_INT : ( '+' | '-' )? INT

A Zomic program is just a series of statements.

compound_statement : statement+

statement
	:	direct_statement
	|	nested_statement
	|	'{' compound_statement '}'

Direct statements

Direct statements are non-nested statements that directly affect one of the four VM variables: location, orientation, scale, or build/move mode.

direct_statement
	:	strut_statement
	|	rotate_statement
	|	scale_statement
	|	build_statement
	|	move_statement

Strut statement

strut_statement : size_expr length_expr? "half"? axis_expr

If the build-mode VM variable is on, make a strut starting at the current location (VM variable), and set the location to the end of the new strut.  Connector balls at each end are added automatically, as necessary.

If the build-mode variable is off, the location is adjusted in the same fashion, but no struts or connectors balls are added to the model.

Before the action is performed, the following adjustments are made: The stated strut size is adjusted by the current scale VM variable.  The stated axis is mapped according to the current orientation VM variable.

The optional length expression allows struts of arbitrary length to be constructed.  The scaled strut size is multiplied by the indicated number before the build or move occurs.

The optional "half" modifier builds or moves by a half-strut length, and is allowed only for green and blue axes.

Size expression

size_expr
	: "size" SIGNED_INT
	| "short" | "medium" | "long"

An absolute scale for Zome struts.  The "short", "medium", and "long" sizes correspond to the standard sizes in the ZomeTool kits.

Size values are simply the powers of tau, with the unit length ("size 0") defined as the diameter of the Zome connector ball in the blue direction.  In other words, a "size 0" blue strut appears as two balls "kissing".  This implies that "size 4" is exactly equivalent to "medium".  Size values can be negative.

Length expression

length_expr
	: SIGNED_INT SIGNED_INT?

A length multiplier for Zome struts.  The two integers together form a "golden number", of the form A*tau+B, where A is the optional second integer, and B is the first integer.  If the second integer is missing, therefore, the length multiplier is just an integer, 0*tau + B.  If the length expression is omitted entirely, the length multiplier is one.

Axis expression

The name of one of the fixed "directions" in the Zome system.  Examples: "red +0" "blue -4" "green +22".  The axis numbers use the indexing from the Zomod language.  A cut-out paper model for an axis "key" is available from the author.

axis_expr : axis_name SIGNED_INT

axis_name : "red" | "blue" | "yellow" | "green" | "orange" | "purple"

The "orange" and "purple" directions are not (yet) available in the physical Zome system, but they represent useful directions.  To see the relationships, run the following script (model credit to Fabien Vienne):

repeat 3 // or as many times as you can stand!
{
short blue +2 blue +2 long blue +2

short blue +5 long purple -0
short blue +5 repeat 2 short red -0
short blue +5 short green -0

short blue +5 blue +5 long blue +5

short blue +2 repeat 2 yellow -0
short blue +2 orange -0
short blue +2

scale +1
}

Scale statement

Increment or decrement the scale VM variable.  The scale variable adjusts the sizes of struts and moves accomplished by the strut_statement.

scale_statement : "scale" SIGNED_INT ( "(" length_expr ")" )?

The required integer is interpreted as a power of tau.  The optional length_expr between parentheses indicate a further multiplicative scaling factor, with the same interpretation as used for strut statements.

Build statement

Set the build-mode VM variable to "on" (building).  Subsequent strut_statements will add struts the model.

build_statement : "build"

Move statement

Set the build-mode VM variable to "off" (just moving).  Subsequent strut_statements will NOT add struts the model, but will still adjust the location VM variable.

move_statement : "move"

Rotate statement

Add a rotation to the current orientation VM variable.  The number of "steps" will be the given integer (or 1, if absent) modulo the number of possible rotations for the given axis.  E.g., "rotate 6 around red +0" is equivalent to "rotate 1 around red +0". 

rotate_statement :	"rotate" SIGNED_INT? "around" axis_expr

The sense of the rotation is best stated by example: "rotate around red +0" maps "blue +0" to "blue +4".

Nested Statements

These are statements of the form <modifier> statement, where the modifier has some temporary effect while the statement executes.  The statement is often compound ("{"..."}").

nested_statement
	:	branch_statement
	|	from_statement
	|	repeat_statement
	|	symmetry_statement
	|	save_statement

Save statement

Execute a statement with "protected" copies of the current VM variables.  Adjustments to the VM variables within the statement will not persist after the save statement.

All the VM variables will be protected if "save all" is used.  Otherwise, only the variable stated will be protected.

save_statement :
		"save"
			( "location"
			| "scale"
			| "orientation"
			| "build"
			| "all"
			)
		statement

From statement

Move the location as if a strut were built, regardless of the current value of the build-mode VM variable.  The statement MUST be a strut statement.

from_statement : "from" strut_statement

This is shorthand for: "save build { move strut_statement }"

Branch statement

Execute a statement and then restore the current location VM variable.  The statement may be compound: "{" ... "}".

branch_statement : "branch" statement

This is shorthand for:  "save location statement".

Symmetry statement

Apply a symmetry operator to the given statement.

symmetry_statement :
		"symmetry"
			( "around" axis_expr
			| "through" ( "center" | SIGNED_INT )
			)?
		statement

There are four variants:

1. Rotational symmetry around an axis.

2. Mirror symmetry through a blue axis

3. Point symmetry through a center (the starting location)

4. Icosahedral symmetry: the statement is repeated with every one of the 60 right-handed orientations applied.  (This preserves "handedness" or "chirality"... see the scripts "greenGiant" or "snubDodec" as examples that takes advantage of this.  Full icosahedral symmetry, with left-handed orientations applied as well, can be achieved simply by adding "symmetry through center" before the symmetry statement.)

For icosahedral symmetry, a "save all" modifier is implicit: "symmetry red +0" is equivalent to "symmetry save all red +0".  This means that the current location, orientation, scale, and build mode will be restored before each of the 60 executions of the nested statement.  The main effect is that the model will be roughly "spherical" around a central point, the location before the start of the symmetry statement.

For point, rotational, and mirror symmetry, a "save orientation" modifier is implicit: "symmetry around red +0 blue +3" is equivalent to "symmetry around red +0 save orientation blue +3".  The location, scale, and build mode are NOT preserved, allowing helical or spiral models, for example.

Repeat statement

Repeat execution of the given statement.  This can be useful for building spirals, helixes, and space-filling structures.

repeat_statement : "repeat" INT statement 

Comments

Comments use the C++ style, both forms:

	// a comment that goes to the end of the line

	/* a comment that does not */