Back to main index

Integration with C++

The Generino source code can be directly integrated with native C++ code. Thanks to this:

The "yellow code"

The Generino and C++ code can cohexist on the same source file thanks to a syntactical coloring done by the Generino editor. For example:

ON EVENT sensorPoll
  temp = analogRead (PIN_SENSOR)
  updateDisplay ();
  SET TIMER sensorPoll TO 100
END

Within the FormalCapture editor, the "yellow code" is obtained by selecting "Free" text mode (F9), while normal code is selected with "Code" (F10):"

Note that all the "yellow" C++ code written in the Generino sources is copied as-is in the generated .ino source. Generino will not make any formal check on it, so all errors will eventually be detected by the Ardunino C++ compiler.

This is how "yellow code" looks on the real editor:

GLOBAL code

Native code enclosed within the GLOBAL/END GLOBAL markers is copied as-is to the C++ source code.

In the example below, the LiquidCrystal library is included and a "lcd" object is created:

GLOBAL
  // include the library code:
  #include 

  // initialize the library with the numbers of the interface pins
  LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
END GLOBAL

SETUP code

Native code enclosed within the SETUP/END SETUP markers is copied as-is to the C++ source code inside the setup function.

SETUP
  // Use the internal reference: this increases resolution since it sets the
  // reference to 1.1V on ATmega328. See docs to know which microprocessors
  // support this.
  analogReference (INTERNAL);

  // set up the LCD's number of columns and rows:
  lcd.begin (16, 2);
END SETUP

Transition code

Within transition, C++ code can be simply inserted by using the "yellow code" function:

ON EVENT sensorPoll
  lcd.clear();
END

Expression code

Within expression, C++ code can simply inserted where an expression is expected by yellow-coloring them. Once yellow-colored, Generino disables any type check.

The example below changes state when the the sd.peek() method return a value non negative:

WHEN sd.peek() >= 0
  SET STATE readingData
END WHEN

Class code

If yellow-code is written inside a class, it will be inserted inside the "class name {...};" C++ declaration. This allows defining custom attributes and methods inside the generated class.

01: CLASS Display
02:   ATTRIBUTE NUMBER temp
03:   TIMER sensorPoll
04: 
05:   void updateDisplay() {
06:     lcd.setCursor (0, 0);
07:     lcd.print ("T=");
08:     lcd.print (temp);
09:   }
10: 
11:   START
12:     updateDisplay ();
13:     SET TIMER sensorPoll TO 100
14:   END START
15: 
16:   STATE ready
17:     ON EVENT sensorPoll
18:       temp = analogRead (PIN_SENSOR)
19:       updateDisplay ();
20:       SET TIMER sensorPoll TO 100
21:     END
22:   END STATE
23: END CLASS

The example above defines an updateDisplay() C++ method at lines 5-9. This method can access at line 8 the Generino attribute temp defined at line 2 because in the generated code it is mapped to a C++ attribute.

At lines 12 and 19, the updateDisplay() C++ method is invoked within the transitions.

Constructor

Generino does not use C++ constructors in its generated code. Its initial settings are done in the setup() function. This frees the C++ constructors for custom initialization without interfering with Generino code.

In the example below, the MyClass class has a C++ constructor receiving a const char* parameter. The C++ constructor parameter can then be supplied to the instance by enclosing it in square brackets [...] at the end of the OBJECT statement:

CLASS MyClass
	int myNumber;
	const char* myName;
	
	// Constructor
	MyClass (const char* n, int x): myName(n), myNumber(x) {}

	STATE myState
	END STATE	
END CLASS

OBJECT MyClass myObject ["HELLO", 1234]