LEVIATHAN v0.1 · in development

Foundations

Lexical & Literals

How Leviathan source text is spelled: what a comment, an identifier, and a keyword look like, and every literal form the lexer recognizes — from binary integers to triple-quoted strings.

Comments

Two forms, exactly as in C-family languages. Block comments do not nest.

// a line comment runs to end of line
/* a block comment
   spans multiple lines */

Identifiers

An identifier matches [A-Za-z_][A-Za-z0-9_]*. The house style is camelCase: each internal word boundary capitalizes the stem after the first — subString, not substring.

Keywords

The reserved words that may not be used as bare identifiers at statement or declaration start:

namespace  class  struct  enum  interface  public  private  new  mutating
distinct   const  get  set  return  var  let  await  bind  inject  use  uses
if  else  while  for  in  match  is  this  true  false
break  continue  do  using  try  catch  throw

The primitive type names int, string, bool, float, and void are not keywords — they are ordinary names resolved to prelude declarations. And attribute, comptime, rule, macro, and as are contextual: ordinary identifiers except at the declaration positions that give them meaning. Keywords like get/is/in may still be used as member names after . or ::.

Literal forms

Every literal the language recognizes, at a glance:

FormExamplesType
integer42, 0, 0xFF, 0b1010int
float3.14float
string"hello", 'hi'string
booleantrue, falsebool
array[1, 2, 3], [], [1..5]Array<T>
range1..10 (inclusive)Range

A Range element inside an array literal spreads: [1..3, 7] is [1, 2, 3, 7].

Integer literals

Decimal, hex (0x/0X), or binary (0b/0B) — there is no octal. An underscore _ separates digits for readability in any base, including a float's fractional digits; it may not lead, trail, or double up.

int million = 1_000_000;
int mask    = 0x1_FF;        // 511
int flags   = 0b1010;        // 10
float pi    = 1_000.000_5;   // separators allowed in fractional digits too

A hex/binary literal is always an int0x1.5 (a dot followed by a digit) is a compile error, not a fractional part, while 0xA..0xF is the .. range operator applied to two hex ints. Hex/binary literals reinterpret their full 64-bit pattern, so 0x8000000000000000 prints the same as 1 << 63.

String literals

Both quote styles lex to string literals and are otherwise identical — ' and " differ only in which character ends the token.

Escapes

Strings are byte-clean through the floor, so an embedded NUL survives rather than terminating the string.

EscapeMeaning
\n \t \r \0newline, tab, carriage-return, NUL
\xNNexactly two hex digits → that byte
\u{H+}1–6 hex digits → the UTF-8 encoding of that Unicode scalar
\" \\ \'the literal quote, backslash, apostrophe
\<other>an unrecognized escape passes the character through (\q is just q)

A surrogate or out-of-range \u{...} scalar decodes to U+FFFD rather than throwing — a compile-time literal has nothing to catch. A malformed \x or \u{...} is left alone: the leading letter passes through as ordinary content.

Interpolation

"...${expr}..." (either quote style) desugars in the parser to concatenation with .toString():

string msg = "code=${resp.status}!";
// exactly equivalent to:
string msg = "code=" + (resp.status).toString() + "!";

\${ escapes a literal ${; a bare $ with no { stays literal (there is no $name shorthand — that syntax belongs to quasiquote holes). An empty or unterminated hole is a compile error. A hole may nest a string literal as long as it uses the opposite quote style from the outer literal.

Raw strings

r"..." / r'...' — a r immediately before a quote opens a literal where backslash is an ordinary character. No escape processing and no ${...} interpolation happen inside. Single-line only; there is no way to embed the delimiter quote. Ideal for regex patterns, Windows paths, and embedded JSON/HTML fixtures.

string pattern = r"\d+\.\d+";     // backslashes are literal
string path    = r"C:\Users\me";

Multiline strings

"""...""" / '''...''' — a literal delimited by three quotes may contain raw newlines and lone embedded quotes (only three in a row closes it). Unlike a raw string, ordinary escape processing and ${...} interpolation still apply inside.

string doc = """
    Dear ${name},
      Welcome aboard.
    """;

Char literals are target-typed

A single-quoted literal is a string by default, but it re-types to char when — and only when — the expected type in context is char and its decoded content is exactly one Unicode scalar. See Types and Strings & Chars for the full rule.

char c = 'a';        // char — the context expects one
var  s = 'a';        // stays string — no char context
bool ok = (c == 'a'); // 'a' re-types to char to match c
string d = "a";       // double-quoted is never a char
Not yet a target-typing site

Call-argument position does not (yet) target-type a bare 'x' to a char parameter — a char-typed value binds fine, but a bare literal argument stays string. This is a deferred surface.

Operators & punctuation

The symbolic tokens the lexer produces:

::  :  ;  ,  .  ..  (  )  {  }  [  ]
=>  =  ==  !=  !  <  >  <=  >=  +  -  *  /  %
+=  -=  *=  /=  %=  <<  >>  &&  ||  &  |  ^  ~  ?  ??  ?.  @

@ introduces an attribute. A backtick-delimited `...` lexes as a quasiquote literal, and inside one $name is a hole. See Expressions for operator precedence.