- Introduction
- Editor
- Get started
- Runtime / VM
Language Guide
Design-Notes
Type System
AutoLang uses a hybrid type system combining static typing with dynamic behavior. Most types are validated at compile time, while Any acts as a universal container that can wrap any value.
Primitive Types
| Type | Description |
|---|---|
| Int | 64-bit signed integer (int64_t) |
| Float | 64-bit floating point (double) |
| Bool | Boolean value (true or false) |
| String | Sequence of characters |
| Any | Universal container type |
Primitive Conversions
To convert between primitive types, you can use syntax that looks like a function call: Int(), Float(). Under the hood, these are not actual functions. The compiler intercepts them as a CastNode and directly emits a dedicated bytecode instruction, meaning primitive conversions have zero function-call overhead.
// 1. Float to Int (Truncates the decimal part)
val pi: Float = 3.14159
val approximatePi: Int = Int(pi)
println(approximatePi) // Output: 3
// 2. Int to Float
val score: Int = 100
val preciseScore: Float = Float(score)
println(preciseScore) // Output: 100.0The Any Container
Any is a special container type. It can wrap any value without changing the original type internally. It is not the root of the inheritance hierarchy.
val number: Int = 5
val text: String = "Hello"
val a: Any = number
val b: Any = text
println(a)
println(b)Nullable Types
Nullable types are declared using ?. Nullable safety is enforced at compile time.
val a: Int? = null
val b: Int = 5
// val c: Int = a // Compile-time error: Cannot assign nullable to non-nullable
val d: Int = 10
println(d)AutoLang does not provide smart casting. You must explicitly unwrap nullable values using !.
Type Checking (is)
The is operator checks the runtime type of a value.
val a: Any = 5
if (a is Int) {
println("a is an Integer")
} else {
println("a is not an Integer")
}Unsafe Cast (as)
The as operator performs an explicit cast. It is allowed when:
- There is an inheritance relationship
- OR one of the types is
Any
If the runtime type is incompatible, a runtime error is thrown. Casting to a nullable type using as is not allowed.
val a: Any = 20
val b = a as Int
println(b * 2) // Output: 40Safe Cast (as?)
The as? operator attempts a safe cast. If the cast fails, null is returned instead of throwing an error.
val a: Any = "Hello"
val b = a as? Int
if (b == null) {
println("Cast failed gracefully")
} else {
println(b)
}Compile-Time Restrictions
If two types have no inheritance relationship and neither is Any, the compiler will reject the cast entirely at compile time.
val text: String = "Hello"
// val number = text as Int // Compile-time errorAdvanced: Runtime Type IDs
For deep integrations or building low-level data structures (like standard library Collections), Autolang provides a special compiler function: getClassId(Type).
- Like magic constants (
__FILE__), it is resolved entirely at compile time. - It returns the unique
Intidentifier of a class or primitive type.
val intTypeId = getClassId(Int)
val stringTypeId = getClassId(String)
println(intTypeId)
println(stringTypeId)
// You can pass these IDs directly to C++ via @native functions!⚡ Want to see how this powers the compiler?
Tricks like getClassId() and CastNode are heavily used under the hood to completely eliminate runtime overhead and avoid expensive reflection.
