Skip to content

feat: extend 'as' keyword for type conversions (as / as?) #39

@mjm918

Description

@mjm918

Description

Extend the existing as keyword for comprehensive type conversions, with as? for fallible conversions.

Syntax

as - Infallible Conversions (always succeed)

var s: string = 42 as string;        // "42"
var s2: string = 3.14 as string;     // "3.14"
var s3: string = true as string;     // "true"
var f: float = 42 as float;          // 42.0
var i: int = 3.7 as int;             // 3 (truncates)
var i2: int = true as int;           // 1
var d: decimal = 42 as decimal;      // 42.00

as? - Fallible Conversions (returns option<T>)

var n: option<int> = "42" as? int;           // some(42)
var n2: option<int> = "abc" as? int;         // none
var n3: option<int> = "FF" as? int(16);      // some(255) - with base
var f: option<float> = "3.14" as? float;     // some(3.14)
var f2: option<float> = "bad" as? float;     // none
var b: option<bool> = "yes" as? bool;        // some(true)
var b2: option<bool> = "maybe" as? bool;     // none
var u: option<uint> = -5 as? uint;           // none (negative)
var u2: option<uint> = 42 as? uint;          // some(42)
var d: option<decimal> = "19.99" as? decimal; // some(19.99)

Conversion Matrix

Infallible (as) - Direct return

From To Example Result
int string 42 as string "42"
int float 42 as float 42.0
int decimal 42 as decimal 42.00
float string 3.14 as string "3.14"
float int 3.7 as int 3
float decimal 3.14 as decimal 3.14
bool string true as string "true"
bool int true as int 1
decimal string d as string "19.99"

Fallible (as?) - Returns option<T>

From To Example Result
string int "42" as? int some(42)
string int "abc" as? int none
string float "3.14" as? float some(3.14)
string bool "yes" as? bool some(true)
string bool "maybe" as? bool none
string decimal "19.99" as? decimal some(19.99)
int uint -5 as? uint none
int uint 42 as? uint some(42)

Bool Parsing Rules

as? bool accepts:

  • true: "true", "1", "yes", "on"
  • false: "false", "0", "no", "off"
  • none: anything else

Restrictions

Type conversion does NOT work on:

  • option<T> - Cannot use as or as? on optional types
  • exception - Cannot use as or as? on exception types
var opt: option<int> = some(42);
var s: string = opt as string;      // ERROR: cannot convert option<T>

var ex: MyException = MyException("error");
var s: string = ex as string;       // ERROR: cannot convert exception

Additional Formatting (std::convert)

For advanced formatting, a minimal std::convert module provides:

use std::convert::*;

var h: string = hex(255);              // "ff"
var b: string = binary(10);            // "1010"
var o: string = octal(8);              // "10"
var p: string = precision(3.14159, 2); // "3.14"

Examples

fn main() {
    // Reading user input
    var input: string = read_line();
    var age: int = (input as? int) ?? 0;
    
    // With else block
    var count: int = input as? int else {
        println("Invalid number, using default");
        return;
    } ?? 0;
    
    // Chained conversion
    var result: string = (42 as float) as string;  // "42.0"
    
    // Type-safe uint conversion
    var positive: uint = some_int as? uint ?? 0;
}

Implementation Notes

Parser Changes

  • Extend as to support as? variant
  • as? followed by type returns option<Type>
  • Optional base syntax for int parsing: as? int(16)

Typechecker Changes

  • Validate conversion is allowed (not from option/exception)
  • Determine if conversion is fallible or infallible
  • Set return type accordingly (T or option)

Codegen

  • Map each conversion to runtime function
  • as calls infallible conversion functions
  • as? calls fallible conversion functions returning option

Implementation Priority

Phase 1: Core as conversions

  • int <-> string, float, decimal
  • float <-> string, int
  • bool <-> string, int

Phase 2: as? fallible conversions

  • string -> int, float, decimal, bool
  • int -> uint

Phase 3: Formatting (std::convert)

  • hex(), binary(), octal()
  • precision()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions