mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-09 09:38:24 +00:00
feat: check type correctness
This commit is contained in:
parent
cc1e367982
commit
a2a3bdbb3e
|
@ -84,6 +84,27 @@ pub fn lowering_error_to_report(
|
||||||
.with_message(format!("Unresolved type {:?}.", name))
|
.with_message(format!("Unresolved type {:?}.", name))
|
||||||
.finish()
|
.finish()
|
||||||
},
|
},
|
||||||
|
LoweringError::UnexpectedType { span, found, expected } => {
|
||||||
|
let mut labels = vec![
|
||||||
|
Label::new((path.clone(), span.into()))
|
||||||
|
.with_message(format!("Unexpected type '{}', expected '{}'", found, expected.kind))
|
||||||
|
.with_color(colors.next())
|
||||||
|
];
|
||||||
|
|
||||||
|
if let Some(span) = expected.span {
|
||||||
|
labels.push(
|
||||||
|
Label::new((path.clone(), span.into()))
|
||||||
|
.with_message(format!("expected '{}' due to this type", expected.kind))
|
||||||
|
.with_color(colors.next())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Report::build(ReportKind::Error, path.clone(), span.lo)
|
||||||
|
.with_code("E3")
|
||||||
|
.with_labels(labels)
|
||||||
|
.with_message(format!("expected type {}.", expected.kind))
|
||||||
|
.finish()
|
||||||
|
},
|
||||||
LoweringError::IdNotFound { span, id } => {
|
LoweringError::IdNotFound { span, id } => {
|
||||||
Report::build(ReportKind::Error, path.clone(), span.lo)
|
Report::build(ReportKind::Error, path.clone(), span.lo)
|
||||||
.with_code("E_ID")
|
.with_code("E_ID")
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
// Based on a cfg
|
// Based on a cfg
|
||||||
|
|
||||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
use std::{
|
||||||
|
collections::{BTreeMap, HashMap, HashSet},
|
||||||
|
fmt,
|
||||||
|
};
|
||||||
|
|
||||||
use edlang_span::Span;
|
use edlang_span::Span;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -207,13 +210,13 @@ pub struct SwitchTarget {
|
||||||
pub targets: Vec<usize>,
|
pub targets: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct TypeInfo {
|
pub struct TypeInfo {
|
||||||
pub span: Option<Span>,
|
pub span: Option<Span>,
|
||||||
pub kind: TypeKind,
|
pub kind: TypeKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum TypeKind {
|
pub enum TypeKind {
|
||||||
Unit,
|
Unit,
|
||||||
Bool,
|
Bool,
|
||||||
|
@ -268,7 +271,50 @@ impl TypeKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
impl fmt::Display for TypeKind {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
TypeKind::Unit => write!(f, "()"),
|
||||||
|
TypeKind::Bool => write!(f, "bool"),
|
||||||
|
TypeKind::Char => write!(f, "char"),
|
||||||
|
TypeKind::Int(ty) => match ty {
|
||||||
|
IntTy::I128 => write!(f, "i128"),
|
||||||
|
IntTy::I64 => write!(f, "i64"),
|
||||||
|
IntTy::I32 => write!(f, "i32"),
|
||||||
|
IntTy::I16 => write!(f, "i16"),
|
||||||
|
IntTy::I8 => write!(f, "i8"),
|
||||||
|
IntTy::Isize => write!(f, "isize"),
|
||||||
|
},
|
||||||
|
TypeKind::Uint(ty) => match ty {
|
||||||
|
UintTy::U128 => write!(f, "u128"),
|
||||||
|
UintTy::U64 => write!(f, "u64"),
|
||||||
|
UintTy::U32 => write!(f, "u32"),
|
||||||
|
UintTy::U16 => write!(f, "u16"),
|
||||||
|
UintTy::U8 => write!(f, "u8"),
|
||||||
|
UintTy::Usize => write!(f, "usize"),
|
||||||
|
},
|
||||||
|
TypeKind::Float(ty) => match ty {
|
||||||
|
FloatTy::F32 => write!(f, "f64"),
|
||||||
|
FloatTy::F64 => write!(f, "f32"),
|
||||||
|
},
|
||||||
|
TypeKind::FnDef(_, _) => todo!(),
|
||||||
|
TypeKind::Str => write!(f, "str"),
|
||||||
|
TypeKind::Ptr(is_mut, inner) => {
|
||||||
|
let word = if *is_mut { "mut" } else { "const" };
|
||||||
|
|
||||||
|
write!(f, "*{word} {}", inner.kind)
|
||||||
|
}
|
||||||
|
TypeKind::Ref(is_mut, inner) => {
|
||||||
|
let word = if *is_mut { "mut" } else { "const" };
|
||||||
|
|
||||||
|
write!(f, "&{word} {}", inner.kind)
|
||||||
|
}
|
||||||
|
TypeKind::Struct(_) => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy)]
|
||||||
pub enum IntTy {
|
pub enum IntTy {
|
||||||
I128,
|
I128,
|
||||||
I64,
|
I64,
|
||||||
|
@ -278,7 +324,7 @@ pub enum IntTy {
|
||||||
Isize,
|
Isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy)]
|
||||||
pub enum UintTy {
|
pub enum UintTy {
|
||||||
U128,
|
U128,
|
||||||
U64,
|
U64,
|
||||||
|
@ -288,7 +334,7 @@ pub enum UintTy {
|
||||||
Usize,
|
Usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy)]
|
||||||
pub enum FloatTy {
|
pub enum FloatTy {
|
||||||
F32,
|
F32,
|
||||||
F64,
|
F64,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use edlang_ast::{Ident, Span};
|
use edlang_ast::{Ident, Span};
|
||||||
|
use edlang_ir::{TypeInfo, TypeKind};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::DefId;
|
use crate::DefId;
|
||||||
|
@ -27,4 +28,10 @@ pub enum LoweringError {
|
||||||
IdNotFound { span: Span, id: DefId },
|
IdNotFound { span: Span, id: DefId },
|
||||||
#[error("feature not yet implemented: {message}")]
|
#[error("feature not yet implemented: {message}")]
|
||||||
NotYetImplemented { span: Span, message: &'static str },
|
NotYetImplemented { span: Span, message: &'static str },
|
||||||
|
#[error("unexpected type")]
|
||||||
|
UnexpectedType {
|
||||||
|
span: Span,
|
||||||
|
found: TypeKind,
|
||||||
|
expected: TypeInfo,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,7 @@ fn lower_function(
|
||||||
}
|
}
|
||||||
|
|
||||||
for stmt in &func.body.body {
|
for stmt in &func.body.body {
|
||||||
lower_statement(&mut builder, stmt, &ret_ty.kind)?;
|
lower_statement(&mut builder, stmt, &ret_ty)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !builder.statements.is_empty() {
|
if !builder.statements.is_empty() {
|
||||||
|
@ -230,7 +230,7 @@ fn lower_function(
|
||||||
fn lower_statement(
|
fn lower_statement(
|
||||||
builder: &mut BodyBuilder,
|
builder: &mut BodyBuilder,
|
||||||
info: &ast::Statement,
|
info: &ast::Statement,
|
||||||
ret_type: &TypeKind,
|
ret_type: &TypeInfo,
|
||||||
) -> Result<(), LoweringError> {
|
) -> Result<(), LoweringError> {
|
||||||
match info {
|
match info {
|
||||||
ast::Statement::Let(info) => lower_let(builder, info),
|
ast::Statement::Let(info) => lower_let(builder, info),
|
||||||
|
@ -249,7 +249,7 @@ fn lower_statement(
|
||||||
fn lower_while(
|
fn lower_while(
|
||||||
builder: &mut BodyBuilder,
|
builder: &mut BodyBuilder,
|
||||||
info: &WhileStmt,
|
info: &WhileStmt,
|
||||||
ret_type: &TypeKind,
|
ret_type: &TypeInfo,
|
||||||
) -> Result<(), LoweringError> {
|
) -> Result<(), LoweringError> {
|
||||||
let statements = std::mem::take(&mut builder.statements);
|
let statements = std::mem::take(&mut builder.statements);
|
||||||
builder.body.blocks.push(BasicBlock {
|
builder.body.blocks.push(BasicBlock {
|
||||||
|
@ -330,11 +330,17 @@ fn lower_while(
|
||||||
fn lower_if_stmt(
|
fn lower_if_stmt(
|
||||||
builder: &mut BodyBuilder,
|
builder: &mut BodyBuilder,
|
||||||
info: &ast::IfStmt,
|
info: &ast::IfStmt,
|
||||||
ret_type: &TypeKind,
|
ret_type: &TypeInfo,
|
||||||
) -> Result<(), LoweringError> {
|
) -> Result<(), LoweringError> {
|
||||||
let cond_ty = find_expr_type(builder, &info.condition).expect("couldnt find cond type");
|
let cond_ty = find_expr_type(builder, &info.condition).expect("couldnt find cond type");
|
||||||
let (condition, condition_ty, cond_span) =
|
let (condition, condition_ty, cond_span) = lower_expr(
|
||||||
lower_expr(builder, &info.condition, Some(&cond_ty))?;
|
builder,
|
||||||
|
&info.condition,
|
||||||
|
Some(&TypeInfo {
|
||||||
|
span: None,
|
||||||
|
kind: cond_ty,
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
let local = builder.add_temp_local(TypeKind::Bool);
|
let local = builder.add_temp_local(TypeKind::Bool);
|
||||||
let place = Place {
|
let place = Place {
|
||||||
|
@ -433,7 +439,16 @@ fn lower_if_stmt(
|
||||||
|
|
||||||
fn lower_let(builder: &mut BodyBuilder, info: &ast::LetStmt) -> Result<(), LoweringError> {
|
fn lower_let(builder: &mut BodyBuilder, info: &ast::LetStmt) -> Result<(), LoweringError> {
|
||||||
let ty = lower_type(&builder.ctx, &info.r#type, builder.local_module)?;
|
let ty = lower_type(&builder.ctx, &info.r#type, builder.local_module)?;
|
||||||
let (rvalue, _ty, _span) = lower_expr(builder, &info.value, Some(&ty.kind))?;
|
let (rvalue, found_ty, _span) = lower_expr(builder, &info.value, Some(&ty))?;
|
||||||
|
|
||||||
|
if ty.kind != found_ty {
|
||||||
|
return Err(LoweringError::UnexpectedType {
|
||||||
|
span: info.span,
|
||||||
|
found: found_ty,
|
||||||
|
expected: ty.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let local_idx = builder.name_to_local.get(&info.name.name).copied().unwrap();
|
let local_idx = builder.name_to_local.get(&info.name.name).copied().unwrap();
|
||||||
builder.statements.push(Statement {
|
builder.statements.push(Statement {
|
||||||
span: Some(info.name.span),
|
span: Some(info.name.span),
|
||||||
|
@ -454,21 +469,25 @@ fn lower_let(builder: &mut BodyBuilder, info: &ast::LetStmt) -> Result<(), Lower
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) -> Result<(), LoweringError> {
|
fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) -> Result<(), LoweringError> {
|
||||||
let (mut place, mut ty, _span) = lower_path(builder, &info.name)?;
|
let (mut place, ty, _span) = lower_path(builder, &info.name)?;
|
||||||
|
let mut ty = TypeInfo {
|
||||||
|
span: None,
|
||||||
|
kind: ty,
|
||||||
|
};
|
||||||
|
|
||||||
for _ in 0..info.deref_times {
|
for _ in 0..info.deref_times {
|
||||||
match &ty {
|
match &ty.kind {
|
||||||
TypeKind::Ptr(is_mut, inner) => {
|
TypeKind::Ptr(is_mut, inner) => {
|
||||||
if !is_mut {
|
if !is_mut {
|
||||||
panic!("trying to mutate non mut ptr");
|
panic!("trying to mutate non mut ptr");
|
||||||
}
|
}
|
||||||
ty = inner.kind.clone();
|
ty = *inner.clone();
|
||||||
}
|
}
|
||||||
TypeKind::Ref(is_mut, inner) => {
|
TypeKind::Ref(is_mut, inner) => {
|
||||||
if !is_mut {
|
if !is_mut {
|
||||||
panic!("trying to mutate non mut ref");
|
panic!("trying to mutate non mut ref");
|
||||||
}
|
}
|
||||||
ty = inner.kind.clone();
|
ty = *inner.clone();
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -546,24 +565,68 @@ fn find_expr_type(builder: &mut BodyBuilder, info: &ast::Expression) -> Option<T
|
||||||
fn lower_expr(
|
fn lower_expr(
|
||||||
builder: &mut BodyBuilder,
|
builder: &mut BodyBuilder,
|
||||||
info: &ast::Expression,
|
info: &ast::Expression,
|
||||||
type_hint: Option<&TypeKind>,
|
type_hint: Option<&TypeInfo>,
|
||||||
) -> Result<(ir::RValue, TypeKind, Span), LoweringError> {
|
) -> Result<(ir::RValue, TypeKind, Span), LoweringError> {
|
||||||
Ok(match info {
|
Ok(match info {
|
||||||
ast::Expression::Value(info) => {
|
ast::Expression::Value(info) => {
|
||||||
let (value, ty, span) = lower_value(builder, info, type_hint)?;
|
let (value, ty, span) = lower_value(builder, info, type_hint)?;
|
||||||
|
|
||||||
|
if let Some(expected_ty) = type_hint {
|
||||||
|
if expected_ty.kind != ty {
|
||||||
|
return Err(LoweringError::UnexpectedType {
|
||||||
|
span,
|
||||||
|
found: ty,
|
||||||
|
expected: expected_ty.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(ir::RValue::Use(value, span), ty, span)
|
(ir::RValue::Use(value, span), ty, span)
|
||||||
}
|
}
|
||||||
ast::Expression::FnCall(info) => {
|
ast::Expression::FnCall(info) => {
|
||||||
let (value, ty, span) = lower_fn_call(builder, info)?;
|
let (value, ty, span) = lower_fn_call(builder, info)?;
|
||||||
|
|
||||||
|
if let Some(expected_ty) = type_hint {
|
||||||
|
if expected_ty.kind != ty {
|
||||||
|
return Err(LoweringError::UnexpectedType {
|
||||||
|
span,
|
||||||
|
found: ty,
|
||||||
|
expected: expected_ty.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(ir::RValue::Use(value, span), ty, span)
|
(ir::RValue::Use(value, span), ty, span)
|
||||||
}
|
}
|
||||||
ast::Expression::Unary(_, _) => todo!(),
|
ast::Expression::Unary(_, _) => todo!(),
|
||||||
ast::Expression::Binary(lhs, op, rhs) => {
|
ast::Expression::Binary(lhs, op, rhs) => {
|
||||||
lower_binary_expr(builder, lhs, op, rhs, type_hint)?
|
let result = lower_binary_expr(builder, lhs, op, rhs, type_hint)?;
|
||||||
|
|
||||||
|
if let Some(expected_ty) = type_hint {
|
||||||
|
if expected_ty.kind != result.1 {
|
||||||
|
return Err(LoweringError::UnexpectedType {
|
||||||
|
span: result.2,
|
||||||
|
found: result.1,
|
||||||
|
expected: expected_ty.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
}
|
}
|
||||||
ast::Expression::Deref(inner) => {
|
ast::Expression::Deref(inner) => {
|
||||||
let (value, ty, span) = lower_expr(builder, inner, type_hint)?;
|
let (value, ty, span) = lower_expr(builder, inner, type_hint)?;
|
||||||
|
|
||||||
|
if let Some(expected_ty) = type_hint {
|
||||||
|
if expected_ty.kind != ty {
|
||||||
|
return Err(LoweringError::UnexpectedType {
|
||||||
|
span,
|
||||||
|
found: ty,
|
||||||
|
expected: expected_ty.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check if its a use directly, to avoid a temporary.
|
// check if its a use directly, to avoid a temporary.
|
||||||
let mut value = match value {
|
let mut value = match value {
|
||||||
RValue::Use(op, _) => match op {
|
RValue::Use(op, _) => match op {
|
||||||
|
@ -580,14 +643,24 @@ fn lower_expr(
|
||||||
}
|
}
|
||||||
ast::Expression::AsRef(inner, mutable) => {
|
ast::Expression::AsRef(inner, mutable) => {
|
||||||
let type_hint = match type_hint {
|
let type_hint = match type_hint {
|
||||||
Some(inner) => match inner {
|
Some(inner) => match &inner.kind {
|
||||||
TypeKind::Ref(_, inner) => Some(&inner.kind),
|
TypeKind::Ref(_, inner) => Some(inner.as_ref()),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
let (mut value, ty, span) = lower_expr(builder, inner, type_hint)?;
|
let (mut value, ty, span) = lower_expr(builder, inner, type_hint)?;
|
||||||
|
|
||||||
|
if let Some(expected_ty) = type_hint {
|
||||||
|
if expected_ty.kind != ty {
|
||||||
|
return Err(LoweringError::UnexpectedType {
|
||||||
|
span,
|
||||||
|
found: ty,
|
||||||
|
expected: expected_ty.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check if its a use directly, to avoid a temporary.
|
// check if its a use directly, to avoid a temporary.
|
||||||
value = match value {
|
value = match value {
|
||||||
RValue::Use(op, _span) => RValue::Ref(*mutable, op, span),
|
RValue::Use(op, _span) => RValue::Ref(*mutable, op, span),
|
||||||
|
@ -652,7 +725,7 @@ fn lower_expr(
|
||||||
.projection
|
.projection
|
||||||
.push(PlaceElem::Field { field_idx: idx });
|
.push(PlaceElem::Field { field_idx: idx });
|
||||||
|
|
||||||
let variant = &struct_body.variants[idx].ty.kind;
|
let variant = &struct_body.variants[idx].ty;
|
||||||
|
|
||||||
let (value, _value_ty, span) = lower_expr(builder, &value.value, Some(variant))?;
|
let (value, _value_ty, span) = lower_expr(builder, &value.value, Some(variant))?;
|
||||||
|
|
||||||
|
@ -672,20 +745,34 @@ fn lower_binary_expr(
|
||||||
lhs: &ast::Expression,
|
lhs: &ast::Expression,
|
||||||
op: &ast::BinaryOp,
|
op: &ast::BinaryOp,
|
||||||
rhs: &ast::Expression,
|
rhs: &ast::Expression,
|
||||||
type_hint: Option<&TypeKind>,
|
type_hint: Option<&TypeInfo>,
|
||||||
) -> Result<(ir::RValue, TypeKind, Span), LoweringError> {
|
) -> Result<(ir::RValue, TypeKind, Span), LoweringError> {
|
||||||
trace!("lowering binary op: {:?}", op);
|
trace!("lowering binary op: {:?}", op);
|
||||||
|
|
||||||
let (lhs, lhs_ty, _) = if type_hint.is_none() {
|
let (lhs, lhs_ty, _) = if type_hint.is_none() {
|
||||||
let ty = find_expr_type(builder, lhs)
|
let ty = find_expr_type(builder, lhs)
|
||||||
.unwrap_or_else(|| find_expr_type(builder, rhs).expect("cant find type"));
|
.unwrap_or_else(|| find_expr_type(builder, rhs).expect("cant find type"));
|
||||||
lower_expr(builder, lhs, Some(&ty))?
|
lower_expr(
|
||||||
|
builder,
|
||||||
|
lhs,
|
||||||
|
Some(&TypeInfo {
|
||||||
|
span: None,
|
||||||
|
kind: ty,
|
||||||
|
}),
|
||||||
|
)?
|
||||||
} else {
|
} else {
|
||||||
lower_expr(builder, lhs, type_hint)?
|
lower_expr(builder, lhs, type_hint)?
|
||||||
};
|
};
|
||||||
let (rhs, rhs_ty, _) = if type_hint.is_none() {
|
let (rhs, rhs_ty, _) = if type_hint.is_none() {
|
||||||
let ty = find_expr_type(builder, rhs).unwrap_or(lhs_ty.clone());
|
let ty = find_expr_type(builder, rhs).unwrap_or(lhs_ty.clone());
|
||||||
lower_expr(builder, rhs, Some(&ty))?
|
lower_expr(
|
||||||
|
builder,
|
||||||
|
rhs,
|
||||||
|
Some(&TypeInfo {
|
||||||
|
span: None,
|
||||||
|
kind: ty,
|
||||||
|
}),
|
||||||
|
)?
|
||||||
} else {
|
} else {
|
||||||
lower_expr(builder, rhs, type_hint)?
|
lower_expr(builder, rhs, type_hint)?
|
||||||
};
|
};
|
||||||
|
@ -827,7 +914,7 @@ fn lower_fn_call(
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
|
|
||||||
for (arg, arg_ty) in info.params.iter().zip(args_ty) {
|
for (arg, arg_ty) in info.params.iter().zip(args_ty) {
|
||||||
let (rvalue, _rvalue_ty, _span) = lower_expr(builder, arg, Some(&arg_ty.kind))?;
|
let (rvalue, _rvalue_ty, _span) = lower_expr(builder, arg, Some(&arg_ty))?;
|
||||||
args.push(rvalue);
|
args.push(rvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -861,7 +948,7 @@ fn lower_fn_call(
|
||||||
fn lower_value(
|
fn lower_value(
|
||||||
builder: &mut BodyBuilder,
|
builder: &mut BodyBuilder,
|
||||||
info: &ast::ValueExpr,
|
info: &ast::ValueExpr,
|
||||||
type_hint: Option<&TypeKind>,
|
type_hint: Option<&TypeInfo>,
|
||||||
) -> Result<(Operand, TypeKind, Span), LoweringError> {
|
) -> Result<(Operand, TypeKind, Span), LoweringError> {
|
||||||
Ok(match info {
|
Ok(match info {
|
||||||
ast::ValueExpr::Bool { value, span } => (
|
ast::ValueExpr::Bool { value, span } => (
|
||||||
|
@ -892,7 +979,7 @@ fn lower_value(
|
||||||
),
|
),
|
||||||
ast::ValueExpr::Int { value, span } => {
|
ast::ValueExpr::Int { value, span } => {
|
||||||
let (ty, val) = match type_hint {
|
let (ty, val) = match type_hint {
|
||||||
Some(type_hint) => match &type_hint {
|
Some(type_hint) => match &type_hint.kind {
|
||||||
ir::TypeKind::Int(int_type) => match int_type {
|
ir::TypeKind::Int(int_type) => match int_type {
|
||||||
ir::IntTy::I128 => (
|
ir::IntTy::I128 => (
|
||||||
ir::TypeKind::Int(ir::IntTy::I128),
|
ir::TypeKind::Int(ir::IntTy::I128),
|
||||||
|
@ -962,7 +1049,7 @@ fn lower_value(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ast::ValueExpr::Float { value, span } => match type_hint {
|
ast::ValueExpr::Float { value, span } => match type_hint {
|
||||||
Some(type_hint) => match &type_hint {
|
Some(type_hint) => match &type_hint.kind {
|
||||||
TypeKind::Float(float_ty) => match float_ty {
|
TypeKind::Float(float_ty) => match float_ty {
|
||||||
ir::FloatTy::F32 => (
|
ir::FloatTy::F32 => (
|
||||||
ir::Operand::Constant(ir::ConstData {
|
ir::Operand::Constant(ir::ConstData {
|
||||||
|
@ -975,7 +1062,7 @@ fn lower_value(
|
||||||
value.parse().unwrap(),
|
value.parse().unwrap(),
|
||||||
))),
|
))),
|
||||||
}),
|
}),
|
||||||
type_hint.clone(),
|
type_hint.kind.clone(),
|
||||||
*span,
|
*span,
|
||||||
),
|
),
|
||||||
ir::FloatTy::F64 => (
|
ir::FloatTy::F64 => (
|
||||||
|
@ -989,7 +1076,7 @@ fn lower_value(
|
||||||
value.parse().unwrap(),
|
value.parse().unwrap(),
|
||||||
))),
|
))),
|
||||||
}),
|
}),
|
||||||
type_hint.clone(),
|
type_hint.kind.clone(),
|
||||||
*span,
|
*span,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -1008,7 +1095,7 @@ fn lower_value(
|
||||||
fn lower_return(
|
fn lower_return(
|
||||||
builder: &mut BodyBuilder,
|
builder: &mut BodyBuilder,
|
||||||
info: &ast::ReturnStmt,
|
info: &ast::ReturnStmt,
|
||||||
return_type: &TypeKind,
|
return_type: &TypeInfo,
|
||||||
) -> Result<(), LoweringError> {
|
) -> Result<(), LoweringError> {
|
||||||
if let Some(value_expr) = &info.value {
|
if let Some(value_expr) = &info.value {
|
||||||
let (value, _ty, span) = lower_expr(builder, value_expr, Some(return_type))?;
|
let (value, _ty, span) = lower_expr(builder, value_expr, Some(return_type))?;
|
||||||
|
|
Loading…
Reference in a new issue