From Luma to Go

The Luma compiler translates Luma source code into idiomatic Go. This ensures both high performance and portability while retaining Luma’s simplicity and expressiveness.

High-Level Overview

Luma is not interpreted. Instead, it compiles to Go code which is then built into a native binary. This brings:

  • Fast execution - same performance as Go.
  • Easy deployment - native cross-platform binaries.
  • Go ecosystem access - potential interop in the future.

Compilation Pipeline

Here’s how the compilation process works:

  • Lexing: Source code is tokenized into symbols.
  • Parsing: Tokens are parsed into an AST (Abstract Syntax Tree).
  • Semantic Analysis: Types and scopes are resolved.
  • Code Generation: The AST is translated into Go code.
  • Go Compilation: Go code is compiled with go build.

Output Structure

Every Luma program gets compiled into a single Go main() file with:

  • All user code translated into idiomatic Go.
  • Core utilities from the Luma standard library injected at the top (e.g. _luma_print, to_int()).
  • Optional func main() includes REPL or CLI interface, depending on the mode.

Type-Aware Codegen

The compiler tracks types explicitly from variable declarations:

x: int = 5
y: float = 3.5
total: float = x + y

This becomes:

x := int(5)
y := float64(3.5)
total := float64(x) + y

The compiler infers and injects coercions automatically depending on expected types. For example:

  • If the variable type is int, the expression is cast to int.
  • Parentheses are respected in mathematical operations.

Core Function Injection

Functions like print(), type(), and to_int() are mapped to internal Go helpers:

print("Hello")

Compiles to:

_luma_print("Hello")

These helpers are injected automatically from the /core folder before user code, enabling fast built-in functionality.

Example

Luma Code:

a: int = 5
b: float = 15.0
result: float = (a + b) / 2
print("Average: ${result}")

Generated Go:

a := int(5)
b := float64(15.0)
result := (float64(a) + b) / float64(2)
_luma_print("Average: " + _luma_sprint(result))

Design Goals

  • Clarity: Go output is readable, debug-friendly, and idiomatic.
  • Coercion logic: Implicit conversions are inserted where the expected type is known.
  • Incremental extensibility: The compiler can grow to support custom backends or transpile to other languages later.
  • No runtime penalty: Once compiled, no Luma runtime is required.
Last updated on