LIA Logo

The LIA Programming Language v1.0.0 Specification [DRAFT]

Revision: 4
Release Date: 30/8/2025
Author: Lawton "Lawtro" Kelly

This document describes the core language specifications and not particularly the current state of LIA-lang. This is simply the target of what LIA-lang should be.

THIS DOCUMENT IS INCOMPLETE: more content is planned to be added to this document.

Table of Contents

Introduction

This specification defines the normative syntax, semantics, and external interface of the LIA programming language. Its goal is to provide a precise, implementation‑agnostic contract for:

Scope: Only the core language and its required runtime behaviors.
Non‑scope: Tooling, build systems, optimization strategies, debugging facilities, editor integration, and prospective future extensions.

Conformance: An implementation is conforming if it:

  1. Accepts all grammatically valid programs defined herein.
  2. Rejects (with a diagnostic) any lexically or syntactically invalid input.
  3. Preserves the specified evaluation order and side‑effects.
  4. Implements the defined type and value categories (including null and void semantics).

Undefined Behavior: Any construct not explicitly covered (e.g. accessing non‑existent object fields) is undefined and may terminate execution or produce implementation‑specific results.

Versioning: This draft targets v1.0.0. Backward incompatible changes after ratification require a major version increment.

"Must" / "Shall"
mandatory.
"Should"
recommended.
"May"
optional.
"Undefined"
intentionally unspecified—implementations are not required to diagnose.
"LIA-lang"
the LIA Programming language

All examples are illustrative; if an example conflicts with a formal rule, the rule governs.

1. Lexical Structure

Character set: ASCII (string contents treated as raw bytes)
Whitespace: space, tab, CR, LF (insignificant outside string literals)
Comments:

1.1 Identifiers

Pattern: [A-Za-z_][A-Za-z0-9_]*
Case-sensitive. Reserved keywords excluded.

1.2 Keywords

function, class, new, var, const, return, if, else, for, loop, while, break, skip, free, import, true, false, null, void, bool, int, float, string

Note that keywords and their aliases aren't particularly reserved when defining variables

Aliases

1.3 Literals

1.4 Operators

1.5 Delimiters

() [] { } , :

2. Types

Primitive core:

S = storage size in bytes; default size when omitted is 32 bits.

Sub‑type Aliases

Default integer width: 32 bits (alias int = int32).

Integers (signed / unsigned):

Floats:

Strings: string, str, text

Composite:

3. Variables

Syntax:

const modifier is parsed; enforcement of immutability is nominal.

Variables with no declared type default to any
Uninitialized variables get null.

4. Statements

5. Functions

Syntax:
function <return_type> <identifier>( <param_list>? ) { block }

Parameters:
<type> <identifier> separated by commas.

Return:
return <expression> (void functions may return without an expression producing null).

No overloading or default parameters.

6. Objects

Literal:
{ <type> <fieldName>: <expression>, ... }

Element type is either explicitly defined or inferred as Any.

7. Arrays

Two forms:

Element type is either explicitly defined or inferred as Any.

8. Classes

class <classname> (args?*) { block }

The main code block acts as the constructor for classes in LIA-lang.
Anything defined in the scope of a class becomes accessible from the class object.
Classes can be instantiated as so new <classname> (args?*).

9. Casting

Prefix type token followed by a parenthesized expression: <type> (expr)

10. Import System

import "<.lia/.llb/.dll path>" (as <identifier>)?

Search path: relative to current working directory. No cycle detection.

11. Memory Management

Once a scope is exited the scope and its contents are removed and freed from memory.
The free() function removes the inputted variable from the scope and frees the memory.

10.1 Memory Allocation Model

Stack Allocation

Heap Allocation

Allocation Behavior

Data TypeAllocation Location
intstack
floatstack
boolstack
nullstack
voidstack
string (< 32 bytes)stack
string (> 32 bytes)heap
Arraysheap
Objectsheap
Classesheap

12. Runtime / Execution Model

LIA-lang is an interpreted programming language meaning execution is handled by a program that reads in the code and executes it based on its operation. LIA uses a Tree‑walk interpreter that executes assembled LIA code. LIA code is assembled into an abstract syntax tree and/or serialised into .ast file before execution or being bundled with an interpreter. Runtime interpreters are either embedded into a compiled binary with assembled LIA bytecode or are separate and read in .ast or .lia files for execution. In the case of a separate interpreter .lia files are parsed into unserialised .ast LIA bytecode before being executed A separate interpreter will deserialise .ast files before executing them. An embedded interpreter will deserialise the LIA bytecode appended to the end of its file after the "LIA\xFF" header before executing it.

Execution Model

Direct Interpretation

Tokeniser
Parser/Assembler
Validator
Optimiser
Interpreter

Compilation

Tokeniser
Parser/Assembler
Validator
Optimiser
Serialiser
Embedder/Compiler

13. Error Handling

Categories:

CategoryExamplesHandling (Typical)
LexicalInvalid tokenAbort parse; diagnostic emitted
SyntaxUnexpected token / structureAbort parse with location
TypeIncompatible assignmentDiagnostic; may abort validation
Runtime (non‑fatal)Missing library functionReport; attempt continue
Runtime (fatal)Calling an undefined functionTerminate with error code

Standard diagnostic format (illustrative):

<KIND>: <MESSAGE>
at <FILEPATH>:<LINE>
<OPTIONAL EXTRA CONTEXT>

Fatal runtime errors terminate the process with an implementation‑defined exit code. Non‑fatal runtime issues may be logged to stderr or console depending on runtime flags.

14. Grammar (EBNF Approximation)

program          ::= statement*
statement        ::= function_decl
                   | var_decl
                   | if_stmt
                   | while_stmt
                   | return_stmt
                   | free_stmt
                   | import_stmt
                   | expression
function_decl    ::= "function" type identifier "(" param_list? ")" block
param_list       ::= param ("," param)*
param            ::= type identifier
var_decl         ::= "var" ("const")? type identifier ("=" expression)?
if_stmt          ::= "if" "(" expression ")" block ("else" block)?
while_stmt       ::= "while" "(" expression ")" block
return_stmt      ::= "return" expression
free_stmt        ::= "free" "(" ident_or_index ("," ident_or_index)* ")"
import_stmt      ::= "import" string_literal
block            ::= "{" statement* "}"
expression       ::= assignment
assignment       ::= binary ("=" assignment)?
binary           ::= unary (op unary)*        # op in precedence order (* /, + -, ==)
unary            ::= ("+" | "-" | cast_prefix) unary | primary
cast_prefix      ::= type "("
primary          ::= number
                   | string_literal
                   | "true" | "false" | "null"
                   | identifier call_or_index?
                   | array_literal
                   | object_literal
                   | "(" expression ")"
call_or_index    ::= "(" arg_list? ")" | "[" expression "]"
arg_list         ::= expression ("," expression)*
array_literal    ::= "[" type? (expression ("," expression)*)? "]"
object_literal   ::= "{" object_field ("," object_field)* "}"
object_field     ::= type identifier ":" expression
ident_or_index   ::= identifier ("[" expression "]")?
type             ::= "int" size? | "uint" size? | "float" size? | "char" size? | "string" | "bool" | "void" | "any"
size             ::= integer_literal

15. Operator Precedence (High → Low)

  1. Unary (++ --)
  2. Multiplicative (* /)
  3. Additive (+ -)
  4. Equality (==)
  5. Assignment (= right-associative)

16. Native Interop

.dll files:

.dll files can be loaded via import or the loadLibrary() native function
.dll public functions will be converted to work with LIA-lang placed in the global scope

.llb files:

.llb files can be loaded via import or the loadLibrary() native function and are essentially libraries specifically made for LIA-lang.
.llb files are technically just .dll files under the hood just with special functionality to interface with LIA-lang

18. Native Functions (Built‑ins)

The following native (built‑in) global functions are provided by the reference interpreter. Availability or exact behavior may vary in other runtimes.

FunctionArgsReturnsDescription
printlnany*voidPrints each argument on its own line (stringifies values).
printany*voidPrints arguments without automatic newline separation.
lenvalueintLength of string / array / object field count.
pusharray item index?voidAppends an item to a specified or last item of an arry
poparray index?voidRemoves the specified or last item of an array
input(none)stringReads a line from standard input (newline trimmed).
assertboolvoidPanics if argument is false.
exitint?(never)Terminates process with optional integer code.
ceilnumberintCeiling of numeric argument.
sinnumberfloatSine (radians).
cosnumberfloatCosine (radians).
tannumberfloatTangent (radians).
logbase, valuefloatLogarithm of value to given base.
expvaluefloate^value.
random(none)floatPseudo‑random float in [0,1].
randomIntmin, maxintPseudo‑random integer in inclusive range.
sleepmsvoidSleeps current thread for milliseconds.
date(none)stringCurrent date (YYYY‑MM‑DD) naive calculation.
timestamp(none)intMilliseconds since Unix epoch.
timestampSeconds(none)intSeconds since Unix epoch.
loadLibrarystringvoidLoads a .dll or .llb library.

19. .AST Bytecode Format

18.1 Headers

HeaderUse
LIA\xFFIndicates the start of AST bytecode when embeded into an executable.
0xABMagic number.
0x01Version header (for future compatability)

18.2 Instructions

TagInstructionData Structure
0x01Program(instructions)[number Of instructions][Instructions*]
0x02Decloration(Identifier, Type, Value)[Identifier][Type][Value]
0x03Assignment(Identifier, Value)[Identifier][Value]
0x04If(condition, body, else_body)[BinaryOp(condition)][Program(body)](else ? 1[Program(else_body)] : 0)
0x05Function(Identifier, Type, args, body)[Identifier][Type][length of args (as u32)][Argument(args)?*][Program(body)]
0x06Argument(identifier, Type)[string(identifier)][Type]
0x07Call(identifier, args)[string(identifier)][length of args (as u32)][Argument(args)?*]
0x08Return(Value)[Value]
0x09BinaryOp(operation, left, right)[string(operation)][AST(left)][AST(right)]
0x0AUnaryOp(operation, Value)[string(operation)][Value]
0x0BLiteral(Type, Value)[Type][Value]
0x0CIdentifier(identifier, index)[string(identifier)](index ? 1[AST(index)] : 0)
0x0DArray(Type, items)[Type][lenth of items (as u32)][Value(items)?*]
0x0EObject(fields[length of fields]([Type][Identifier(indentifiers)][Value])?*
0x0FWhile(condition, body)[BinaryOp(condition)][Program(body)]
0x10Free(Identifier)[length of identifiers (as u32)][Identifier?*]
0x11Class(Identifier, args, body)[Identifier][length of args (as u32)][Argument(args)?*][Program(body)]
0x12NewInstance(Identifier, args)[Identifier][length of args (as u32)][Argument(args)?*]

18.3 Types

TagTypeData Structure
0x01Int(signed, size)[signed (0/1 | u8)][size (u8)]
0x02Float(size)[size (u8)]
0x04StringNA
0x05BoolNA
0x04VoidNA
0x04NullNA
0x04AnyNA
0x04Class(identifier)[String(identifier)]

18.4 Literal Values

TypeData Structure
Int(signed, size)[<u/i><size>]
Float(size)[f<size>]
Bool[0/1]
String[string length][string]

20. Implementation Recommendations


Status: Draft baseline for v1.0.0 core.