Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions compiler/hash-codegen/src/lower/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,12 @@ impl<'a, 'b, Builder: BlockBuilderMethods<'a, 'b>> FnBuilder<'a, 'b, Builder> {
(CastTy::Int(in_ty), CastTy::Int(_)) => {
builder.int_cast(value, out_ty, in_ty.is_signed())
}
(CastTy::Ref, CastTy::Int(IntCastKind::UInt)) => {
builder.ptr_to_int(value, out_ty)
}
(CastTy::Int(IntCastKind::UInt), CastTy::Ref) => {
builder.int_to_ptr(value, out_ty)
}
(CastTy::Int(in_ty), CastTy::Float) => {
if in_ty.is_signed() {
builder.si_to_fp(value, out_ty)
Expand All @@ -368,6 +374,9 @@ impl<'a, 'b, Builder: BlockBuilderMethods<'a, 'b>> FnBuilder<'a, 'b, Builder> {
Ordering::Equal => value,
}
}
_ => {
unreachable!("invalid cast from `{:?}` to `{:?}`", in_cast_ty, out_cast_ty)
}
};

let value = OperandValue::Immediate(new_value);
Expand Down
18 changes: 18 additions & 0 deletions compiler/hash-ir/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! this module provides the [CastKind] type which is used to classify
//! casts at the top level within RValue positions.

use hash_repr::ty::RefKind;
use hash_storage::store::statics::StoreId;

use crate::ty::{ReprTy, ReprTyId};
Expand All @@ -26,6 +27,14 @@ pub enum CastKind {
/// A float to float cast conversion, either converting from a `f32` into a
/// `f64` or vice versa.
FloatToFloat,

/// A conversion between a reference (i.e. a pointer &T | &raw T) to
/// an integral type.
RefToInt,

/// A conversion between a platform unsigned integer to a
/// reference (i.e. a pointer &T | &raw T).
IntToRef,
}

impl CastKind {
Expand All @@ -39,6 +48,8 @@ impl CastKind {
(Some(CastTy::Int(_)), Some(CastTy::Float)) => Self::IntToFloat,
(Some(CastTy::Float), Some(CastTy::Int(_))) => Self::FloatToInt,
(Some(CastTy::Float), Some(CastTy::Float)) => Self::FloatToFloat,
(Some(CastTy::Ref), Some(CastTy::Int(IntCastKind::UInt))) => Self::RefToInt,
(Some(CastTy::Int(IntCastKind::UInt)), Some(CastTy::Ref)) => Self::IntToRef,
_ => panic!(
"attempting to cast between non-primitive types: src: `{}`, dest: `{}`",
src, dest
Expand All @@ -65,6 +76,9 @@ pub enum IntCastKind {

/// Converting into a `bool` type.
Bool,

/// Converting a reference to `usize`.
Ptr,
}

impl IntCastKind {
Expand All @@ -85,6 +99,9 @@ pub enum CastTy {

/// Floating-point type casts.
Float,

/// Reference to a memory location.
Ref,
}

impl CastTy {
Expand All @@ -97,6 +114,7 @@ impl CastTy {
ReprTy::Char => Some(Self::Int(IntCastKind::Char)),
ReprTy::Bool => Some(Self::Int(IntCastKind::Bool)),
ReprTy::Float(_) => Some(Self::Float),
ReprTy::Ref(_, _, RefKind::Raw | RefKind::Normal) => Some(Self::Ref),
_ => None,
})
}
Expand Down
44 changes: 44 additions & 0 deletions stdlib/prelude.hash
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,50 @@ println := (message: str) => {
print("\n")
}

/// The `input` function, this allows for reading of strings from the
/// standard input.
input := (prompt: Option<str>) -> str => {
STDIN := 0 // We need top level constants!

match prompt {
Option::Some(value) => print(value),
Option::None => {}
}

buf := libc::malloc(1024);
mut offset := 0usize

// Now let's read in an input using syscall.
loop {
left := libc::read(STDIN, buf, 1024)

if left <= 0 {
break;
}

offset += cast<_, usize>(left)

// if the last read character was a `\n`, then we want to
// break.
//
// @@Todo: we need to be able to index into an array.
arr := transmute<_, [u8]>(SizedPointer(buf, offset));
last_char := cast<_, char>(arr[offset - 1]);
if last_char == '\n' {
break;
}
}

// Don't remove the newline in the end.
if offset > 1 {
offset -= 1
}

// Now transmute the buffer into a string
raw_str := SizedPointer(buf, offset);
transmute<SizedPointer, str>(raw_str)
}

refl := <T, a: T> => () -> {a ~ a} => {
Equal::Refl(a)
}
Expand Down