Skip to content

Commit

Permalink
tutorial update
Browse files Browse the repository at this point in the history
  • Loading branch information
robertmuth committed Jun 27, 2024
1 parent d27a2b0 commit e7f42fe
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 57 deletions.
105 changes: 77 additions & 28 deletions FrontEndDocs/casting.md
Original file line number Diff line number Diff line change
@@ -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.
68 changes: 39 additions & 29 deletions FrontEndDocs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
```
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
```
Expand Down Expand Up @@ -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.

Expand All @@ -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
Expand All @@ -459,19 +462,26 @@ Functions are declared like so:
<STATEMENTS>*
```

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
Expand Down Expand Up @@ -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
Expand All @@ -674,7 +684,7 @@ The optional label can be used to name the block to exit.
...
-- exits the block, label1
break label1
...
```

### Trap Statements
Expand Down Expand Up @@ -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

Expand All @@ -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 |

0 comments on commit e7f42fe

Please sign in to comment.