Update spec
This commit is contained in:
parent
4a83c3b9df
commit
028895ce7f
1 changed files with 106 additions and 9 deletions
115
spec.txt
115
spec.txt
|
|
@ -50,7 +50,7 @@ Literals:
|
||||||
'a' -> u8 (ascii only?)
|
'a' -> u8 (ascii only?)
|
||||||
'猫'u -> u32
|
'猫'u -> u32
|
||||||
|
|
||||||
TODO: string literals? fixed-size arrays? built-in spans? Probably built-in spans (potentially defined in prelude.psl)
|
// TODO: string literals? fixed-size arrays? built-in spans? Probably built-in spans (defined in prelude.psl)
|
||||||
"hello, world" -> utf-8 string
|
"hello, world" -> utf-8 string
|
||||||
"здарова, братки"u -> utf-32 string
|
"здарова, братки"u -> utf-32 string
|
||||||
|
|
||||||
|
|
@ -72,7 +72,7 @@ Array declaration:
|
||||||
Null pointer literal:
|
Null pointer literal:
|
||||||
let p: u32* = null // special like empty array literal, type cannot be inferred
|
let p: u32* = null // special like empty array literal, type cannot be inferred
|
||||||
|
|
||||||
Variables must always be initialized. (TODO: really? What about arrays? Maybe need special syntax for zero-initialization or mass-initialization. Alternative: default to zero-initialization)
|
Variables must always be initialized. // TODO: really? What about arrays? Maybe need special syntax for zero-initialization or mass-initialization. Alternative: default to zero-initialization
|
||||||
Const variables must be initialized with a const expression (any expression that doesn't include non-const values).
|
Const variables must be initialized with a const expression (any expression that doesn't include non-const values).
|
||||||
|
|
||||||
======== OPERATORS ========
|
======== OPERATORS ========
|
||||||
|
|
@ -126,7 +126,7 @@ Casting:
|
||||||
|
|
||||||
The only implicit casting allowed is T mut* -> T* (maybe?)
|
The only implicit casting allowed is T mut* -> T* (maybe?)
|
||||||
Any integer/floating-point types can be cast to each other.
|
Any integer/floating-point types can be cast to each other.
|
||||||
Any pointer types can be cast to each other (TODO: alignment? UB or safe fallback? Probably UB.)
|
Any pointer types can be cast to each other // TODO: alignment? UB or safe fallback? Probably UB.
|
||||||
|
|
||||||
Ternary if operator:
|
Ternary if operator:
|
||||||
if condition then true_value else false_value
|
if condition then true_value else false_value
|
||||||
|
|
@ -150,7 +150,7 @@ Special built-ins:
|
||||||
|
|
||||||
======== FLOW CONTROL ========
|
======== FLOW CONTROL ========
|
||||||
|
|
||||||
Flow control:
|
Conditionals:
|
||||||
if condition:
|
if condition:
|
||||||
statements
|
statements
|
||||||
else if condition:
|
else if condition:
|
||||||
|
|
@ -158,6 +158,7 @@ Flow control:
|
||||||
else:
|
else:
|
||||||
statements
|
statements
|
||||||
|
|
||||||
|
While loop:
|
||||||
while condition:
|
while condition:
|
||||||
statements
|
statements
|
||||||
if x:
|
if x:
|
||||||
|
|
@ -165,7 +166,38 @@ Flow control:
|
||||||
if y:
|
if y:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
TODO: for loops? iterator/range interface?
|
Iterator interface:
|
||||||
|
get(it) returns the currently pointed-to value
|
||||||
|
get_ref(it) returns the pointer to the currently pointed-to value
|
||||||
|
next(it) returns the next iterator
|
||||||
|
|
||||||
|
Range interface:
|
||||||
|
begin(range) returns the begin iterator
|
||||||
|
end(range) returns the end iterator
|
||||||
|
|
||||||
|
For loop:
|
||||||
|
Operates only on ranges.
|
||||||
|
|
||||||
|
for x in range(10):
|
||||||
|
do_something(x)
|
||||||
|
|
||||||
|
i is immutable within the loop body.
|
||||||
|
|
||||||
|
Modifiable ranges use special syntax for pointers to elements:
|
||||||
|
|
||||||
|
for &x in array:
|
||||||
|
*x += 1
|
||||||
|
|
||||||
|
The loop is equivalent to
|
||||||
|
|
||||||
|
mut begin = begin(range)
|
||||||
|
let end = end(range)
|
||||||
|
while begin != end:
|
||||||
|
let x = get(begin) // or get_ref(x) for pointer loop
|
||||||
|
statements
|
||||||
|
begin = next(begin)
|
||||||
|
|
||||||
|
The prelude contains an implementation of range interface for built-in arrays.
|
||||||
|
|
||||||
======== STRUCTS ========
|
======== STRUCTS ========
|
||||||
|
|
||||||
|
|
@ -184,7 +216,7 @@ Struct field access:
|
||||||
let p = &r
|
let p = &r
|
||||||
let y = p.height // field access through pointer is the same
|
let y = p.height // field access through pointer is the same
|
||||||
|
|
||||||
TODO: inner struct functions maybe? to act as namespace/module containers
|
// TODO: inner struct functions maybe? to act as namespace/module containers
|
||||||
|
|
||||||
======== FUNCTIONS ========
|
======== FUNCTIONS ========
|
||||||
|
|
||||||
|
|
@ -195,12 +227,37 @@ Function definition:
|
||||||
func bar(x: f32): // deduced return type unit
|
func bar(x: f32): // deduced return type unit
|
||||||
print(x)
|
print(x)
|
||||||
|
|
||||||
|
Function arguments are automatically immutable (as if declared with let).
|
||||||
|
|
||||||
// External function: name taken literally as `powf`
|
// External function: name taken literally as `powf`
|
||||||
// and C calling convention assumed
|
// and C calling convention assumed
|
||||||
foreign func powf(x: f32, y: f32) -> f32 // no implementation
|
foreign func powf(x: f32, y: f32) -> f32 // no implementation
|
||||||
|
|
||||||
TODO: function overloading? Probably requires selecting a specific overload using `as` operator to save to a value (but not on call site)
|
// TODO: mutable function arguments?
|
||||||
TODO: alternative - Rust-like traits? More powerful, but complicates the language
|
|
||||||
|
// TODO: function overloading? Probably requires selecting a specific overload using `as` operator to save to a value (but not on call site)
|
||||||
|
// TODO: alternative - Rust-like traits, aka parametric polymorphism?
|
||||||
|
|
||||||
|
======== TEMPLATES ========
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// Definitely monomorphized.
|
||||||
|
// Parametric (C++ templates) vs ad-hoc (Rust traits, Haskell typeclasses)?
|
||||||
|
//
|
||||||
|
// Ad-hoc:
|
||||||
|
// + More powerful
|
||||||
|
// + Less concepts in the core language
|
||||||
|
// + Simpler to use in basic cases
|
||||||
|
// - Bad error messages (can be improved with concepts)
|
||||||
|
// - Slow compilation (due to type-checking each instantiation)
|
||||||
|
//
|
||||||
|
// Parametric:
|
||||||
|
// + Cleaner, stricter
|
||||||
|
// + Faster compilation (type-checking only once)
|
||||||
|
// + Better error messages
|
||||||
|
// - Less powerful
|
||||||
|
// - Harder to use in basic cases (e.g. have to declare type constraints or create new traits for any desired per-type behavior)
|
||||||
|
// - A bunch of new required language concepts (trait, impl, constraint), much more complicated to implement in compiler
|
||||||
|
|
||||||
======== TYPE OF TYPES ========
|
======== TYPE OF TYPES ========
|
||||||
|
|
||||||
|
|
@ -233,10 +290,50 @@ E.g.
|
||||||
// else:
|
// else:
|
||||||
// return y
|
// return y
|
||||||
|
|
||||||
|
======== PRELUDE ========
|
||||||
|
|
||||||
|
Prelude is a special source file implicitly included in any project (unless explicitly requested otherwise).
|
||||||
|
|
||||||
|
It contains:
|
||||||
|
|
||||||
|
An array_view template struct:
|
||||||
|
|
||||||
|
struct array_view<t: type>:
|
||||||
|
size: u64
|
||||||
|
data: t*
|
||||||
|
|
||||||
|
A specialization for strings:
|
||||||
|
|
||||||
|
const string_view = array_view<u8>
|
||||||
|
|
||||||
|
(String literals compile into string_view objects.)
|
||||||
|
|
||||||
|
Range interface for built-in arrays and for array_view.
|
||||||
|
|
||||||
|
Numeric ranges with signatures
|
||||||
|
|
||||||
|
range(end) // begin implicitly zero
|
||||||
|
range(begin, end) // step implicitly one
|
||||||
|
range(begin, end, step)
|
||||||
|
|
||||||
|
that allow iteration like
|
||||||
|
|
||||||
|
for i in range(10):
|
||||||
|
for i in range(5u, 10u):
|
||||||
|
for i in range(1.0, 10.0, 0.5):
|
||||||
|
|
||||||
======== MODULES AND IMPORTS ========
|
======== MODULES AND IMPORTS ========
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
// A build system / package metadata? How to e.g. conditionally add some files based on environment (maybe just forbid that)?
|
||||||
|
// How to describe platform-dependent behavior?
|
||||||
|
// * Different files - who decides which files to include?
|
||||||
|
// * Compile-time built-ins - how flexible are they?
|
||||||
|
// Can we create a different type based on platform?
|
||||||
|
// Important for some posix stuff like timespec or threads
|
||||||
|
// * Special compiler intrinsics/attributes/macros/whatever - need a new concept in the language
|
||||||
|
// Maybe a good thing - can merge with alignment specification and other stuff
|
||||||
|
|
||||||
======== STANDARD LIBRARY ========
|
======== STANDARD LIBRARY ========
|
||||||
|
|
||||||
// TODO: containers, memory management, strings?
|
// TODO: containers, memory management, strings, io, math, threads, networking(?)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue