The COBOL binding
The Clunkyard robot API in COBOL, through a generated, logic-free layer over
the robot core's C ABI (docs/design/robot-core.md,
section 5.3). clunkyard.cpy and clunkyard_cobol.c are generated by
protocol/v2/codegen/bindings/cobol.js (make api); nothing here is written
by hand but the Makefile and the test's fixed C, test/support.c.
- Install:
make install SDK=/opt/clunkyard/sdkputs the copybook and the compiled layer,clunkyard_cobol.o, in$(SDK)/bindings/cobol. - Build:
cobc -x -free -I/opt/clunkyard/sdk/bindings/cobol bot.cob /opt/clunkyard/sdk/bindings/cobol/clunkyard_cobol.o /opt/clunkyard/sdk/lib/libclunkyard.a -lm. The core links statically. - Test:
make test SDK=...builds the generated conformance program on the installed layer and runs it against every API vector, exact against the core.
CALL "CY-READ" USING CY-GAME CY-STATE reads one message a turn and fills
both records: every fact is CY-<SUBSYSTEM>-<MEMBER> (CY-ME-HEADING,
CY-SCANNER-LAST-ARC, CY-SENSORS-NEAREST-RANGE), with an 88-level
-FOUND or -NONE beside it, and a list has -COUNT and a table.
CY-SESSION-EVENT-HELLO, -STATE and -END say what was read, and
CALL "CY-SEND" answers it. Every other core function is a by-reference
CALL under its C name in COBOL case, with no handle and the result in the
last argument: CALL "CY-GUN-LEAD" USING CY-SENSORS-NEAREST SHOT-POWER CY-SOLUTION.
RETURN-CODE is the core's status, 0 for found and 1 for none
(CY-OK, CY-NONE). Each control field is its own call
(CALL "CY-DRIVE-TURN" USING TURN), so only the fields called are set. Text
in is NUL-terminated (Z"TRACK"). The layer's names are in COBOL case
because the core's own C names (cy_gun_fire) are taken by its by-value
functions.
COBOL's own COMPUTE on COMP-2 is not IEEE arithmetic, so a robot that
must match the other languages to the bit asks the core (CY-ANGLES-...).
A tiny robot
IDENTIFICATION DIVISION.
PROGRAM-ID. TINY.
DATA DIVISION.
WORKING-STORAGE SECTION.
COPY "clunkyard.cpy".
01 ONE-SECOND USAGE COMP-2 VALUE 1.
01 SHOT-RESERVE USAGE COMP-2 VALUE 10.
01 SEARCH-THROTTLE USAGE COMP-2 VALUE 0.75.
01 SEARCH-TURN USAGE COMP-2 VALUE 0.25.
01 SEARCH-ARC USAGE COMP-2 VALUE 40.
01 TRACK-THROTTLE USAGE COMP-2 VALUE 0.5.
01 TRACK-ARC USAGE COMP-2 VALUE 10.
01 TURN-LOW USAGE COMP-2 VALUE -1.
01 TURN-HIGH USAGE COMP-2 VALUE 1.
01 SHOT-POWER USAGE COMP-2.
01 OFF-BEARING USAGE COMP-2.
01 TURN USAGE COMP-2.
01 CAN-FIRE PIC S9(9) COMP-5.
PROCEDURE DIVISION.
PERFORM UNTIL CY-SESSION-EVENT-END
CALL "CY-READ" USING CY-GAME CY-STATE
IF RETURN-CODE < 0
STOP RUN
END-IF
EVALUATE TRUE
WHEN CY-SESSION-EVENT-HELLO CALL "CY-SEND"
WHEN CY-SESSION-EVENT-STATE PERFORM TAKE-TURN CALL "CY-SEND"
END-EVALUATE
END-PERFORM
STOP RUN.
TAKE-TURN.
IF CY-SENSORS-NEAREST-NONE
CALL "CY-DRIVE-THROTTLE" USING SEARCH-THROTTLE
CALL "CY-DRIVE-TURN" USING SEARCH-TURN
CALL "CY-SCANNER-HEADING" USING CY-ME-HEADING
CALL "CY-SCANNER-ARC" USING SEARCH-ARC
CALL "CY-STATUS-TEXT" USING Z"SEARCH"
CALL "CY-STATUS-VALUE" USING CY-SCANNER-LAST-ARC
EXIT PARAGRAPH
END-IF
CALL "CY-GUN-POWER-FOR-FLIGHT-TIME" USING CY-SENSORS-NEAREST-RANGE ONE-SECOND SHOT-POWER
CALL "CY-GUN-LEAD" USING CY-SENSORS-NEAREST SHOT-POWER CY-SOLUTION
IF RETURN-CODE = CY-OK
CALL "CY-GUN-AIM-HEADING" USING CY-SOLUTION-HEADING
CALL "CY-GUN-AIM-PITCH" USING CY-SOLUTION-PITCH
ELSE
CALL "CY-GUN-AIM-HEADING" USING CY-SENSORS-NEAREST-BEARING
CALL "CY-GUN-AIM-PITCH" USING CY-SENSORS-NEAREST-ELEVATION
END-IF
CALL "CY-GUN-CAN-FIRE" USING SHOT-POWER SHOT-RESERVE CAN-FIRE
IF CAN-FIRE = 1
CALL "CY-GUN-FIRE"
CALL "CY-GUN-POWER" USING SHOT-POWER
END-IF
CALL "CY-ANGLES-ANGLE-DIFF" USING CY-SENSORS-NEAREST-BEARING CY-ME-HEADING OFF-BEARING
CALL "CY-ANGLES-CLAMP" USING OFF-BEARING TURN-LOW TURN-HIGH TURN
CALL "CY-DRIVE-THROTTLE" USING TRACK-THROTTLE
CALL "CY-DRIVE-TURN" USING TURN
CALL "CY-SCANNER-HEADING" USING CY-SENSORS-NEAREST-BEARING
CALL "CY-SCANNER-ARC" USING TRACK-ARC
CALL "CY-STATUS-TEXT" USING Z"TRACK"
CALL "CY-STATUS-VALUE" USING CY-SENSORS-NEAREST-RANGE.
Names
Every entry of the robot API 2.0.0 in COBOL. names.md has every language side by side.
| Canonical | Form | COBOL |
|---|---|---|
match.mode |
property | CY-MATCH-MODE |
match.ruleset |
property | CY-MATCH-RULESET |
match.control |
property | CY-MATCH-CONTROL |
match.robots |
property | CY-MATCH-ROBOTS |
match.is_3d |
property | CY-MATCH-IS-3D |
match.tick_rate |
property | CY-MATCH-TICK-RATE |
match.max_ticks |
property | CY-MATCH-MAX-TICKS |
match.robot_id |
call | CALL "CY-ROBOT-ID" |
clock.tick |
property | CY-CLOCK-TICK |
clock.seconds |
property | CY-CLOCK-SECONDS |
clock.remaining_ticks |
property | CY-CLOCK-REMAINING-TICKS |
arena.size |
property | CY-ARENA-SIZE |
arena.gravity |
property | CY-ARENA-GRAVITY |
arena.terrain_kind |
property | CY-ARENA-TERRAIN-KIND |
arena.ground_height |
call | CALL "CY-ARENA-GROUND-HEIGHT" |
me.health |
property | CY-ME-HEALTH |
me.position |
property | CY-ME-POSITION |
me.velocity |
property | CY-ME-VELOCITY |
me.heading |
property | CY-ME-HEADING |
me.pitch |
property | CY-ME-PITCH |
me.roll |
property | CY-ME-ROLL |
me.angular_velocity |
property | CY-ME-ANGULAR-VELOCITY |
me.attitude |
property | CY-ME-ATTITUDE |
me.grounded |
property | CY-ME-GROUNDED |
me.altitude |
property | CY-ME-ALTITUDE |
me.applied |
property | CY-ME-APPLIED |
battery.charge |
property | CY-BATTERY-CHARGE |
battery.capacity |
property | CY-BATTERY-CAPACITY |
battery.regen |
property | CY-BATTERY-REGEN |
battery.sustainable_drive |
property | CY-BATTERY-SUSTAINABLE-DRIVE |
battery.compute |
property | CY-BATTERY-COMPUTE |
battery.drive_cost |
call | CALL "CY-BATTERY-DRIVE-COST" |
drive.hover_lift |
property | CY-DRIVE-HOVER-LIFT |
drive.set |
control | CALL "CY-DRIVE-THROTTLE", CALL "CY-DRIVE-TURN", … |
drive.forces |
control | CALL "CY-DRIVE-THRUST", CALL "CY-DRIVE-STRAFE", … |
drive.get |
call | CALL "CY-DRIVE-GET-THROTTLE", CALL "CY-DRIVE-GET-TURN", … |
gun.aim_now |
property | CY-GUN-AIM-NOW |
gun.cooldown_ticks |
property | CY-GUN-COOLDOWN-TICKS |
gun.spread |
property | CY-GUN-SPREAD |
gun.max_power |
property | CY-GUN-MAX-POWER |
gun.damage_scale |
property | CY-GUN-DAMAGE-SCALE |
gun.can_fire |
call | CALL "CY-GUN-CAN-FIRE" |
gun.shot_speed |
call | CALL "CY-GUN-SHOT-SPEED" |
gun.shot_cost |
call | CALL "CY-GUN-SHOT-COST" |
gun.reload_ticks |
call | CALL "CY-GUN-RELOAD-TICKS" |
gun.shot_damage |
call | CALL "CY-GUN-SHOT-DAMAGE" |
gun.power_for_speed |
call | CALL "CY-GUN-POWER-FOR-SPEED" |
gun.power_for_flight_time |
call | CALL "CY-GUN-POWER-FOR-FLIGHT-TIME" |
gun.lead |
call | CALL "CY-GUN-LEAD" |
gun.lead_point |
call | CALL "CY-GUN-LEAD-POINT" |
gun.aim |
control | CALL "CY-GUN-AIM-HEADING", CALL "CY-GUN-AIM-PITCH" |
gun.fire |
control | CALL "CY-GUN-FIRE", CALL "CY-GUN-POWER" |
gun.get |
call | CALL "CY-GUN-GET-AIM-HEADING", CALL "CY-GUN-GET-AIM-PITCH", … |
scanner.last |
property | CY-SCANNER-LAST |
scanner.proximity_range |
property | CY-SCANNER-PROXIMITY-RANGE |
scanner.reach |
call | CALL "CY-SCANNER-REACH" |
scanner.arc_for_reach |
call | CALL "CY-SCANNER-ARC-FOR-REACH" |
scanner.set |
control | CALL "CY-SCANNER-HEADING", CALL "CY-SCANNER-ARC", … |
scanner.get |
call | CALL "CY-SCANNER-GET-HEADING", CALL "CY-SCANNER-GET-ARC", … |
sensors.contacts |
property | CY-SENSORS-CONTACTS |
sensors.nearest |
property | CY-SENSORS-NEAREST |
sensors.cues |
property | CY-SENSORS-CUES |
sensors.contact |
call | CALL "CY-SENSORS-CONTACT" |
sensors.position_of |
call | CALL "CY-SENSORS-POSITION-OF" |
tracker.cue |
property | CY-TRACKER-CUE |
tracker.nearest_bearing_rate |
property | CY-TRACKER-NEAREST-BEARING-RATE |
tracker.velocity |
call | CALL "CY-TRACKER-VELOCITY" |
tracker.position |
call | CALL "CY-TRACKER-POSITION" |
tracker.last_seen |
call | CALL "CY-TRACKER-LAST-SEEN" |
tracker.configure |
call | CALL "CY-TRACKER-CONFIGURE" |
nav.zone |
property | CY-NAV-ZONE |
nav.zone.margin |
call | CALL "CY-NAV-ZONE-MARGIN" |
nav.zone.contains |
call | CALL "CY-NAV-ZONE-CONTAINS" |
nav.zone.distance_from |
call | CALL "CY-NAV-ZONE-DISTANCE-FROM" |
nav.storm |
property | CY-NAV-STORM |
nav.storm.margin |
call | CALL "CY-NAV-STORM-MARGIN" |
nav.storm.contains |
call | CALL "CY-NAV-STORM-CONTAINS" |
nav.storm.distance_from |
call | CALL "CY-NAV-STORM-DISTANCE-FROM" |
nav.hill |
property | CY-NAV-HILL |
nav.hill.margin |
call | CALL "CY-NAV-HILL-MARGIN" |
nav.hill.contains |
call | CALL "CY-NAV-HILL-CONTAINS" |
nav.hill.distance_from |
call | CALL "CY-NAV-HILL-DISTANCE-FROM" |
nav.pickups |
property | CY-NAV-PICKUPS |
nav.nearest_pickup |
call | CALL "CY-NAV-NEAREST-PICKUP" |
nav.field_distance |
call | CALL "CY-NAV-FIELD-DISTANCE" |
score.me |
property | CY-SCORE-ME |
score.best |
property | CY-SCORE-BEST |
score.armour |
property | CY-SCORE-ARMOUR |
angles.normalize |
call | CALL "CY-ANGLES-NORMALIZE" |
angles.angle_diff |
call | CALL "CY-ANGLES-ANGLE-DIFF" |
angles.bearing_to |
call | CALL "CY-ANGLES-BEARING-TO" |
angles.elevation_to |
call | CALL "CY-ANGLES-ELEVATION-TO" |
angles.direction |
call | CALL "CY-ANGLES-DIRECTION" |
angles.distance |
call | CALL "CY-ANGLES-DISTANCE" |
angles.clamp |
call | CALL "CY-ANGLES-CLAMP" |
status.set |
control | CALL "CY-STATUS-TEXT", CALL "CY-STATUS-VALUE" |
status.get |
call | CALL "CY-STATUS-GET-TEXT", CALL "CY-STATUS-GET-VALUE" |
raw.number |
call | CALL "CY-RAW-NUMBER" |
raw.text |
call | CALL "CY-RAW-TEXT" |
raw.has |
call | CALL "CY-RAW-HAS" |
raw.flag |
call | CALL "CY-RAW-FLAG" |
raw.count |
call | CALL "CY-RAW-COUNT" |
raw.line |
call | CALL "CY-RAW-LINE" |
raw.extra |
call | CALL "CY-RAW-EXTRA" |
session.event |
property | CY-SESSION-EVENT |
session.next |
call | CALL "CY-SESSION-NEXT" |
session.send |
call | CALL "CY-SESSION-SEND" |
session.forfeit |
call | CALL "CY-SESSION-FORFEIT" |
session.log |
call | CALL "CY-SESSION-LOG" |
session.feed |
call | CALL "CY-SESSION-FEED" |
session.reply |
call | CALL "CY-SESSION-REPLY" |