Skip to content

Commit

Permalink
Fix most type errors from the new print functions
Browse files Browse the repository at this point in the history
  • Loading branch information
jfecher committed Mar 19, 2022
1 parent 0f2b49e commit 50dc604
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 30 deletions.
30 changes: 20 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ See the [website](https://antelang.org) and [language tour](https://antelang.org
- [x] [Article on the sugar for immediately invoked recursive functions (loop/recur)](https://antelang.org/docs/language/#loops)
- [ ] Article on interactions between `mut`, `ref`, and passing by reference
- [ ] Article on autoboxing recursive types for polymorphic pointer types
- [ ] Refinement Types
- [ ] Cranelift backend for faster debug builds
- [~] Refinement Types (in progress)
- [x] Cranelift backend for faster debug builds
- [ ] Algebraic Effects
- [ ] Incremental compilation metadata
- [ ] REPL

Expand Down Expand Up @@ -88,10 +89,11 @@ than development updates.

### Building

Ante currently requires llvm 13.0 while building. If you already have this installed with
sources, you may be fine building with `cargo build` alone. If `cargo build` complains
about not finding any suitable llvm version, the easiest way to build llvm is through `llvmenv`.
In that case, you can build from source using the following:
Ante currently optionally requires llvm 13.0 while building. If you already have this installed with
sources, you may be fine building with `cargo install --path .` alone. If cargo complains
about not finding any suitable llvm version, you can either choose to build ante without
the llvm backend via `cargo install --path . --no-default-features` or you can build llvm from
source, either via `llvmenv` or `cmake` as covered in the next sections.

#### Linux and Mac

Expand All @@ -111,18 +113,26 @@ location and re-running `cargo build`.

#### Windows

Note: LLVM is notoriously difficult to build on windows. If you're a windows user who has tried
the following and still cannot build llvm, I highly recommend trying out ante without the llvm
backend via `cargo install --path . --no-default-features`.

That being said, here is one way to build llvm via llvmenv on windows:

```shell
$ cargo install llvmenv
$ llvmenv init
$ llvmenv build-entry -G VisualStudio -j7 12.0.1
$ llvmenv global 12.0.1
$ for /f "tokens=*" %a in ('llvmenv prefix') do (set LLVM_SYS_120_PREFIX=%a)
$ llvmenv build-entry -G VisualStudio -j7 13.0.0
$ llvmenv global 13.0.0
$ for /f "tokens=*" %a in ('llvmenv prefix') do (set LLVM_SYS_130_PREFIX=%a)
$ cargo build
```
You can confirm your current version of llvm by running `llvmenv version`
or `llvm-config`
##### CMake
If the above steps don't work for you, you can try [building llvm from source
with cmake](https://www.llvm.org/docs/CMake.html). If you're on windows this
requires you to have Visual Studio 2017 or later installed already.
Expand All @@ -145,6 +155,6 @@ done, move on to compiling llvm and ante:
$ cmake --build .
$ cmake --build . --target install
$ cd ..
$ set LLVM_SYS_120_PREFIX=/absolute/path/to/llvm-build
$ set LLVM_SYS_130_PREFIX=/absolute/path/to/llvm-build
$ cargo build
```
17 changes: 5 additions & 12 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
- Kind checking!
- `llvm::Generator::convert_type` needs be fixed for generic types and possibly sum types as well
- Locations should be stored in a `types::traits::Impl` for better error messages for trait errors
- Allocate all ast nodes in a pool, and change them to store node IDs instead of hard references
- Variadic functions. Goal: support `extern printf: (ref char) ... -> int`
- cleanup `resolve_definitions` and friends in name resolution. Their use of DefinitionNodes is
one of the less satisfying uses of `unsafe` in this codebase. This would be trivial if we
allocated nodes in a pool since we could store the node ID instead and wouldn't have to worry
about storing the mutable reference to a node.
- cleanup `ast::If` codegen
- cleanup `required_definitions` in name resolution (is it still needed?)
- Move towards using the `salsa` library and possibly removing ModuleCache

- Audit uses of `typechecker::unify` to maybe specialize them to improve error messages for type errors
- Improve parser error messages
- cranelift or c backend
- Improve type checker error messages
- 'type mismatch' should be more specific
- wrong number of parameters used points to definition rather than callsite or both
- Declare-before use for impls
- Support variadic functions in cranelift backend. Goal: support `extern printf: (ref char) ... -> int`
6 changes: 3 additions & 3 deletions examples/codegen/iter.an
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ impl MyIterable i32 i32 with
if x <= 0 then None
else Some (x, x - 1)

iter iterable f =
my_iter iterable f =
match mynext iterable
| None -> ()
| Some (elem, rest) ->
f elem
iter rest f
my_iter rest f

iter 10 print
my_iter 10 print

// args: --delete-binary
// expected stdout:
Expand Down
23 changes: 22 additions & 1 deletion src/cranelift_backend/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ pub fn call_builtin<'c>(args: &[Ast<'c>], context: &mut Context, builder: &mut F
"EqChar" => eq_char(context, builder),
"EqBool" => eq_bool(context, builder),

"sign_extend" => sign_extend(context, builder),
"zero_extend" => zero_extend(context, builder),
"truncate" => truncate(context, builder),

"deref" => deref(context, builder),
"transmute" => transmute(context, builder),

Expand Down Expand Up @@ -170,7 +174,24 @@ fn deref(context: &mut Context, builder: &mut FunctionBuilder) -> CraneliftValue

fn transmute(context: &mut Context, builder: &mut FunctionBuilder) -> CraneliftValue {
let param1 = context.current_function_parameters[0];
// TODO: multiple returns if argument is a struct
let target_type = builder.func.signature.returns[0].value_type;
builder.ins().bitcast(target_type, param1)
}

fn sign_extend(context: &mut Context, builder: &mut FunctionBuilder) -> CraneliftValue {
let param1 = context.current_function_parameters[0];
let target_type = builder.func.signature.returns[0].value_type;
builder.ins().sextend(target_type, param1)
}

fn zero_extend(context: &mut Context, builder: &mut FunctionBuilder) -> CraneliftValue {
let param1 = context.current_function_parameters[0];
let target_type = builder.func.signature.returns[0].value_type;
builder.ins().uextend(target_type, param1)
}

fn truncate(context: &mut Context, builder: &mut FunctionBuilder) -> CraneliftValue {
let param1 = context.current_function_parameters[0];
let target_type = builder.func.signature.returns[0].value_type;
builder.ins().ireduce(target_type, param1)
}
26 changes: 26 additions & 0 deletions src/llvm/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ pub fn call_builtin<'g, 'c>(args: &[Ast<'c>], generator: &mut Generator<'g>) ->
"EqChar" => eq_char(generator),
"EqBool" => eq_bool(generator),

"sign_extend" => sign_extend(generator),
"zero_extend" => zero_extend(generator),

"truncate" => truncate(generator),

"deref" => deref_ptr(generator),
"transmute" => transmute_value(generator),

Expand Down Expand Up @@ -188,3 +193,24 @@ fn transmute_value<'g>(generator: &mut Generator<'g>) -> BasicValueEnum<'g> {
let ret = current_function.get_type().get_return_type().unwrap();
generator.builder.build_bitcast(x, ret, "transmute").as_basic_value_enum()
}

fn sign_extend<'g>(generator: &mut Generator<'g>) -> BasicValueEnum<'g> {
let current_function = generator.current_function();
let x = current_function.get_nth_param(0).unwrap().as_basic_value_enum().into_int_value();
let ret = current_function.get_type().get_return_type().unwrap().into_int_type();
generator.builder.build_int_s_extend(x, ret, "sign_extend").as_basic_value_enum()
}

fn zero_extend<'g>(generator: &mut Generator<'g>) -> BasicValueEnum<'g> {
let current_function = generator.current_function();
let x = current_function.get_nth_param(0).unwrap().as_basic_value_enum().into_int_value();
let ret = current_function.get_type().get_return_type().unwrap().into_int_type();
generator.builder.build_int_z_extend(x, ret, "zero_extend").as_basic_value_enum()
}

fn truncate<'g>(generator: &mut Generator<'g>) -> BasicValueEnum<'g> {
let current_function = generator.current_function();
let x = current_function.get_nth_param(0).unwrap().as_basic_value_enum().into_int_value();
let ret = current_function.get_type().get_return_type().unwrap().into_int_type();
generator.builder.build_int_truncate(x, ret, "sign_extend").as_basic_value_enum()
}
2 changes: 1 addition & 1 deletion src/types/traitchecker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ fn solve_normal_constraint<'c>(constraint: &TraitConstraint,
/// Each matching impl will be returned along with all of its required impls from any `given`
/// constraints it may have in an element of the returned `Vec`.
///
/// For example, if our constraint is `Print i32` and we have he impls
/// For example, if our constraint is `Print i32` and we have the impls
/// `impl Print a given Cast a string` and
/// `impl Print i32` in scope then our returned set of matching impls will be
/// ```
Expand Down
32 changes: 29 additions & 3 deletions stdlib/prelude.an
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ impl Cast (Maybe m) string given Cast m string with
| Some val -> "Some (" ++ cast val ++ ")"
| None -> "None"

// Incomplete list of int -> int casts. TODO: Add more as appropriate
impl Cast u64 char with cast _ = builtin "truncate"

impl Cast i32 i64 with cast _ = builtin "sign_extend"

/// Represents a failable type cast from a to b
trait TryCast a b with
Expand All @@ -99,14 +103,28 @@ impl TryCast a b given Cast a b with
try_cast a = Some (cast a)


impl TryCast i64 u64 with
try_cast x =
if x < 0 then None
else Some (transmute x)

impl TryCast u64 i64 with
try_cast x =
if x > 9_223_372_036_854_775_807 then None
else Some (transmute x)



// Huge block of builtin numeric operators incoming
trait Add n with (+): n - n -> n
impl Add a given Int a with (+) _ _ = builtin "AddInt"
impl Add float with (+) (_: float) (_: float) : float = builtin "AddFloat"
impl Add char with (+) (_: char) (_: char) : char = builtin "AddInt"

trait Sub n with (-): n - n -> n
impl Sub a given Int a with (-) _ _ = builtin "SubInt"
impl Sub float with (-) (_: float) (_: float) : float = builtin "SubFloat"
impl Sub char with (-) (_: char) (_: char) : char = builtin "SubInt"

trait Mul n with (*): n - n -> n
impl Mul a given Int a with (*) _ _ = builtin "MulInt"
Expand All @@ -124,6 +142,9 @@ trait Eq t with (==): t - t -> bool
impl Eq a given Int a with (==) _ _ = builtin "EqInt"
impl Eq float with (==) (_: float) (_: float) : bool = builtin "EqFloat"

impl Eq char with (==) (_: char) (_: char) : bool = builtin "EqChar"
impl Eq bool with (==) (_: bool) (_: bool) : bool = builtin "EqBool"

(not) a = if a then false else true
(!=) l r = not (l == r)

Expand Down Expand Up @@ -173,7 +194,7 @@ deref (_: ref t) : t =
builtin "deref"

deref_ptr (p: Ptr t) : t =
deref <| cast p
deref <| transmute p

null = cast 0usz : Ptr a

Expand Down Expand Up @@ -233,6 +254,11 @@ impl Print float with printne _ = panic "float printing is currently disabled"
impl Print string with printne s = print_c_string (s.c_string)
impl Print (Ptr char) with printne s = print_c_string s

unwrap (m: Maybe t) : t =
match m
| Some x -> x
| None -> panic "Tried to unwrap a None value"

// Naive replacement for printf which isn't supported by the cranelift backend
print_unsigned (x: u64) : unit =
if x >= 10 then print_unsigned (x / 10)
Expand All @@ -245,9 +271,9 @@ print_signed (x: i64) (min: i64) (min_string: string) : unit =
printne min_string
else
putchar '-'
print_unsigned <| cast (0-x)
print_unsigned <| unwrap <| try_cast (0-x)
else
print_unsigned (cast x)
print_unsigned <| unwrap <| try_cast x

print_c_string (s: Ptr char) : unit =
go s i =
Expand Down

0 comments on commit 50dc604

Please sign in to comment.