/* Language enables implementing dynamic typing using operator overloads and the Any type. Any type is a bundle of typeid and a pointer to value. Current semantics of the Any dictate that values that get assigned to Any values, they get implicitly converted to a pointer and a type. a: Any = 10 // This sentence allocates 10 on the stack a: Any = a + 10 // This also allocates on stack a: Any = a // Does not allocate, takes pointer to a a: Any = array[1] // Does not allocate, takes pointer to value in array The general picture you can take from this is that if we are referencing something it will take a pointer to it. If the operation results in a new value it will allocate the result on stack and make a pointer out of it. Have to be mindful of the lifetime. */ storage: [32]S64 len : S64 "+" :: (a: Any, b: Any): Any result: Any = storage[len++] if a.type == S64 && b.type == S64 *(result.data->*S64) = *(a.data->*S64) + *(b.data->*S64) return result "+" :: (a: Any, b: S64): Any result: Any = storage[len++] if a.type == S64 *(result.data->*S64) = *(a.data->*S64) + b return result "==" :: (a: Any, b: S64): Bool result := false if a.type == S64 result = *(a.data->*S64) == b return result "==" :: (a: Any, b: Any): Bool result := false if a.type == S64 && b.type == S64 result = *(a.data->*S64) == *(b.data->*S64) return result main :: (): int a: Any = 10 b: Any = 20 c := a + b Assert(c.type == S64 && c == 30) Assert(a+b+a==c+(5+5)) return 0