diff --git a/FrontEndDocs/casting.md b/FrontEndDocs/casting.md index f6c367ac..5ce35d31 100644 --- a/FrontEndDocs/casting.md +++ b/FrontEndDocs/casting.md @@ -1,44 +1,93 @@ -# Cwerg Casting and Conversion +# Cwerg Casting and Implicit Conversion -## No cast required (implicit conversion) +## Overview -mut ptr T -> ptr T -mut slice T -> slice T +| Notation | Description | +| --------------------- | -------------------------------------------------------------------- | +| wrap_as(E, T) -> E | convert value to enum or wrapped type | +| unwrap(E) -> E | convert enum or wrapped type to underlying type | +| narrow_as(E, T) -> E | convert union value to actual type | +| widen_as(E, T) -> E | convert value to union | +| as(E, T) -> E | converts between numerical types | +| bitwise_as(E, T) -> E | convert expression to a type of same width, including int to pointer | +| unsafe_as(E, T) -> E | convert between pointers | -sum A|B|C -> sum A|B|C|D|E -A -> sum A|B|C|D|E +## wrap_as / unwrap -mut array T size -> mut slice T -mut array T size -> slice T -array T size -> slice T +`unwrap` converts a value of a wrapped type or enum type to the underlying type. -For array constants `array T size -> slice T` -will materialized the array constant in -readonly memory. +``` +enum color u8: + red 1 + green 2 + blue 3 +static_assert unwrap(color:green) == 2_u8 -## Regular cast +``` -u8 -> u16, u32, u64, s16, s32, s64 -u16 -> u32, u64, s32, s64 -u32 -> u64, s64 +`wrap_as` is the inverse operation: -s8 -> s16, s32, s64 -s16 -> s32, s64 -s32 -> s64 +``` +static_assert wrap(2, color) == color:green +``` -r32 -> r64 +Another example using wrapped type +``` +@wrapped type temperature_celsius = u16 -## Bitcasts +global freezing_point auto = wrap_as(100, temperature_celsius) +``` -s32 <-> u32 <-> r32 -s64 <-> u64 <-> r64 +## narrowing / widening -sint <-> uint <-> ptr T +TBD -## Unsafe cast +## Regular/numerical cast (`as`) -ptr T -> mut ptr T -slice T -> mut slice T +Conversation between these numerical types attempting +to preserve the value as much as possible -TBD +* u8, u16, u32, u64 +* s8, s16, s32, s64 +* r32, r64 + +## Bitcasts (`bitwise_as`) + +* s32/u32 <-> r32 +* s64/u64 <-> r64 +* sint/uint <-> ptr T + +## Unsafe cast (`unsafe_as`) + +* ptr A -> ptr B +* ptr T -> mut ptr T +* slice T -> mut slice T + + + +## No cast required (implicit conversion) + +### drop mutability + +mut ptr T -> ptr T +mut slice T -> slice T + +### convert to a wider union + + +sum A|B|C -> sum A|B|C|D|E +A -> sum A|B|C|D|E + +This can be made explcit with the `widen_as` operation +but is rare needed. + +### array to slice conversion + +mut array T size -> mut slice T +mut array T size -> slice T +array T size -> slice T + +For array constants `array T size -> slice T` +will materialized the array constant in +readonly memory. diff --git a/FrontEndDocs/tutorial.md b/FrontEndDocs/tutorial.md index 13588b18..08957c5a 100644 --- a/FrontEndDocs/tutorial.md +++ b/FrontEndDocs/tutorial.md @@ -2,10 +2,7 @@ Cwerg tries to find the right balance between language expressiveness and compiler implementation complexity. The hope is to reach a sweet spot above what C gives us today. A language that makes it convenient to write system software like operating systems and compilers. - -## Philosophy - -Above all Cwerg is meant to be a small language that can be maintained by a single person. Since small is subjective we have set a complexity budget for about 10kLOC for a compiler frontend with basic optimizations. + So Cwerg is meant to be a small language that can be maintained by a single person. Since small is subjective we have set a complexity budget for about 10kLOC for a compiler frontend with basic optimizations. ## Highlights @@ -46,7 +43,7 @@ Cwerg use a Python inspired syntax where the indentation level is significant. We give some examples below to convey a general feeling for the language. -The details should become clear after reading through the tutorial. +The details should become clear after reading the rest of the tutorial. More examples can be found here: https://github.com/robertmuth/Cwerg/tree/master/FrontEnd/ConcreteSyntax/TestData @@ -198,7 +195,7 @@ The caret goes in front of type. Array dimension go in front of the element type: ``` --- 10 element array of element type u32 + -- 10 element array of element type u32 [10]u32 ``` @@ -216,10 +213,10 @@ Slices are essentially fat pointers consisting of pointer to the first element o and a length. ``` --- regular slice -slice(u32) --- mutable slice -slice!(u32) + -- regular slice + slice(u32) + -- mutable slice + slice!(u32) ``` ### Function types @@ -296,7 +293,7 @@ The type `t1` is said to be a wrapped type. Tagged unions can be declared like so: ``` -union(s32, void, u8, ^sint, [32]u8)) + union(s32, void, u8, ^sint, [32]u8)) ``` Note, that there are no names - only types. In case that the same type is @@ -349,18 +346,18 @@ Number literals may contain underscores ("_") which are ignored. Since Cwerg doe Array literals are declared like so: ``` -[5]s32{1, 2, 3} + [5]s32{1, 2, 3} ``` If there are fewer initializers than the array size, the last value will repeated. So this is equivalent to: ``` -[5]s32{1, 2, 3, 3, 3} + [5]s32{1, 2, 3, 3, 3} ``` If no initializer is provided, zero will be used. initializers for specific indices can declared like so: ``` -[5]s32{1:6, 3:9} + [5]s32{1:6, 3:9} ``` This is equivalent to: ``` @@ -419,7 +416,7 @@ and must be have one of the following kinds: ## Top Level Declations -By default all top level desclations are module private. +By default all top level declarations are module private. The `@pub` annotation will export the declaration and thereby make it visible to the importing module. @@ -436,7 +433,13 @@ global a_global_const u64 = 7_u64 ``` Cwerg has limit type inference so this could be simplified to either: -`global a_global_const u64 = 7` or `global a_global_const = 7_u64`. +``` +global a_global_const u64 = 7 +``` +or +``` +global a_global_const = 7_u64 +``` ### Global Variables @@ -459,19 +462,26 @@ Functions are declared like so: * ``` +Functions can only have one result. + + ### Enums, Types (Typedefs) and Recs (Structs) These were covered in the Type Section above -#### Macros -TBD - see [Macros](macros.md) +### Static Asserts +Static asserts are checked at compile time. Example: +``` +-- this ensures that we are on a 64bit s ystem +static_assert sizeof(^u8) == 8 +``` -### Static Asserts +#### Macros -TBD +TBD - see [Macros](macros.md) ## Statements @@ -663,7 +673,7 @@ Exit the enclosing `block`, `while` or `for` statement. The optional label can be used to name the block to exit. ``` block label1; - + ... block label2: ... -- exits the block, label2 @@ -674,7 +684,7 @@ The optional label can be used to name the block to exit. ... -- exits the block, label1 break label1 - + ... ``` ### Trap Statements @@ -751,11 +761,18 @@ Note, operator precendence has yet to be finalized | pinc(P, E [, E]) -> P | increment pointer with optional bounds check | | pdec(P, E [, E]) -> P | decrement pointer with optional bounds check | | unwrap(E) -> E | convert expression of a wrapped type to the underlying type | +| is(E, T) -> bool | check if union is of given type | | type(E) -> T | type of expression | | typeidof(E) -> typeid | typeid of an expression of union type | | uniondelta(T, T) -> T | type delta of two union type expressions | | stringify(E) -> []u8 | convert an expression to a textual representation | +Legend: +* E: expression +* T: type expression +* P: pointer value +* F: record field name +* S: slice ### Expression Statements @@ -779,10 +796,3 @@ let sign s8 = expr: TBD - see [Casting](casting.md) - - -| Notation | Description | -| ----------------- | ------------------------------------------ | -| as(E, T) -> E | casts with run-time checks | -| wrapas(E, T) -> E | convert expression to a wrapped type | -| bitas(E, T) -> E | convert expression to a type of same width |