---
title: Tutorial 28 Designing a Mini G-code DSL
description: Creating your own language for 3D printing.
---
Tutorial 28 Designing a Mini G-code DSL
1. Lesson Header
- Lesson Number: 28
- Level: Advanced
- Title: Designing a Mini G-code DSL
- Estimated Duration: 45 Minutes
- Prerequisites: Lesson 27 (Python Generation), Lesson 16 (Parametric)
- What You Will Build: A "Turtle Graphics" style DSL for G-code.
2. Concept Introduction
What is a DSL?
A Domain Specific Language.
G-code is a low-level assembly language (G1 X10 Y10).
We want a high-level language:square(10)circle(20)move_to(50, 50)
This abstraction hides the complexity of G1, E calculations, and coordinate tracking.
3. Machine State Explanation
The "Context" Object.
To build a DSL, we need an object (in Python/JS) that tracks the machine state virtually.
- Current X, Y, Z.
- Current E (Total extruded).
- Current Speed.
- Mode (Relative/Absolute).
When you call move(10), the context updates its internal X position and writes the corresponding G1 command.
4. Command Breakdown
- Class/Object: Encapsulate state.
- Methods:
forward(),turn(),up(),down().
5. Minimal Working Example
The Turtle.
Imagine a Logo Turtle that extrudes plastic.t = Turtle()t.forward(10) -> Writes G1 X10 E...t.right(90) -> Updates internal angle.
6. Visual Representation
Interactive preview is available in the interactive reader.
7. Build Exercise
Task: Build a Python Class GcodeTurtle.
Methods:
- __init__(filename): Open file.
- set_speed(f): Write G1 F....
- move(dist): Move forward dist mm. Calculate new X/Y based on angle.
- turn(angle): Update internal angle.
- extrude(amount): Move E axis.
- finish(): Write footer and close.
Usage:
bot = GcodeTurtle("turtle.gcode")
bot.set_speed(3000)
for i in range(4):
bot.move(50)
bot.turn(90)
bot.finish()
8. Deep Insight Section
Abstraction Cost.
Every layer of abstraction adds overhead but increases safety.
Our GcodeTurtle can automatically check boundaries:
"If next_x > 200, raise Error: 'Out of Bounds'".
Raw G-code would just crash the printer.
9. Common Failure Modes
- State Drift: If your Python math (
float) drifts from the printer's internal step count (int), long prints might end up slightly off. (Usually negligible). - Z-Tracking: Turtles are usually 2D. Adding
up()anddown()for Z-hops requires tracking Z state carefully.
10. Real-World Application
Parametric CAD to G-code.
Some workflows export solid or mesh geometry and slice it directly.
SVG to G-code.
Laser cutter software (LightBurn) reads vector shapes (DSL) and converts them to G-code paths.
11. Final Clean Version
The Mini-Engine:
import math
class GcodeTurtle:
def __init__(self, filename):
self.f = open(filename, "w")
self.x = 0
self.y = 0
self.z = 0
self.e = 0
self.angle = 0 # Degrees
self.e_per_mm = 0.05
# Header
self.f.write("G21\nG90\nM83\nG28\nG1 Z0.2 F3000\n")
def set_speed(self, speed):
self.f.write(f"G1 F{speed}\n")
def move(self, distance, extrude=True):
rad = math.radians(self.angle)
dx = distance * math.cos(rad)
dy = distance * math.sin(rad)
self.x += dx
self.y += dy
cmd = f"G1 X{self.x:.3f} Y{self.y:.3f}"
if extrude:
e_amount = distance * self.e_per_mm
cmd += f" E{e_amount:.5f}"
self.e += e_amount
self.f.write(cmd + "\n")
def turn(self, angle):
self.angle += angle
def finish(self):
self.f.write("G28 X0 Y0\n")
self.f.close()
print("Done.")
# Usage
t = GcodeTurtle("square.gcode")
t.set_speed(2000)
for _ in range(36): # 36-sided polygon (Circle-ish)
t.move(10)
t.turn(10)
t.finish()
12. Stretch Challenge
Challenge: Add arc(radius, angle) to the Turtle.
This is hard!
You have to calculate the center of the circle based on current heading and radius, then issue a G2 or G3 command.G2 X[Target] Y[Target] I[Offset] J[Offset].
Hint: The Offset (I, J) is the vector from Start Point to Center.