Skip to content

Language Guide

Andrew Matthews edited this page Aug 14, 2025 · 2 revisions

Language Guide

A living overview of fifthlang syntax and semantics. The language is evolving; examples reflect current tests.

Basics

  • File extension: .5th
  • Whitespace-insensitive where unambiguous
  • Statements end with ; inside blocks; function bodies use {}

Types

Primitive types supported (mapped to .NET):

  • int (Int32)
  • long (Int64)
  • float (Single/float32)
  • double (Double/float64)
  • bool (Boolean)
  • string (String)

User-defined types and classes exist but are evolving.

Functions

Return type annotation follows the parameter list.

  • main(): int { return 42; }
  • foo(b: Bar, b2: Baz): Sqz {}

Overloading is supported by parameter types/arity.

  • foo(i: int): string { return "child"; }
  • foo(s: string): string { return s; }

Variables and declarations

  • a: int;
  • a: int = 5;
  • a = 5 * 6;

Expressions and operators

Binary operators seen in tests:

  • Arithmetic: +, -, *, /, ** (pow), %
  • Comparison: ==, !=, <, <=, >, >=
  • Logical: &&, ||, ~ (xor)
  • Bitwise: &, |, <<, >>

Unary operators:

  • +, -, !

Literals:

  • Integers, floats (0.0, 4.940656458e-324), doubles (suffix d supported in parser tests), strings, booleans.

Control flow

If/else:

  • if (cond) { ... }
  • if (cond) { ... } else { ... }

While:

  • while (cond) { ... }

Collections

List literals and comprehensions are present:

  • xs: int[] = [1, 2, 3]; // ListLiteral
  • ys: int[] = [x * 2 for x in xs]; // ListComprehension

Note: Concrete syntax for [] and comprehensions may evolve; consult tests in test/ast-tests.

Properties and member access

  • p.Weight = p.Weight + 1; // MemberAccessExp

Destructuring parameters (experimental)

Tests indicate destructuring into nested bindings in parameters:

  • foo(({name, vitals: { height, weight }}): Person): int { ... }

See Recursive Destructuring for a clear calculate_bmi example and why this capability (destructuring directly in parameter lists) is not currently available in C#.

Types and inference

  • The compiler annotates nodes with types via a TypeAnnotationVisitor
  • Simple inference promotes int arithmetic to float on division
  • Comparison/logical expressions result in bool
  • Unsupported ops default to unknown type (with errors recorded)

Interop and codegen

  • The current backend emits .NET IL, mapping primitive types to IL primitives (int32, float32, etc.)
  • End-to-end tests validate IL structure (.assembly, .method, return types)

Limitations and status

  • Early alpha; grammar and semantics are changing
  • Some features are stubs or under active development
  • Expect breaking changes between commits

Learn more

Clone this wiki locally