Add type from let through parser to MIR
This commit is contained in:
parent
cdbc4593a8
commit
fb876e3ef5
@ -59,7 +59,7 @@ pub struct FunctionCallExpression(pub String, pub Vec<Expression>, pub TokenRang
|
||||
pub struct IfExpression(pub Expression, pub Block, pub Option<Block>, pub TokenRange);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LetStatement(pub String, pub Expression, pub TokenRange);
|
||||
pub struct LetStatement(pub String, pub Option<Type>, pub Expression, pub TokenRange);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ImportStatement(Vec<String>, pub TokenRange);
|
||||
|
@ -188,6 +188,7 @@ impl Parse for LetStatement {
|
||||
stream.expect(Token::Semi)?;
|
||||
Ok(LetStatement(
|
||||
variable,
|
||||
None, // TODO add possibility to name type
|
||||
expression,
|
||||
stream.get_range().unwrap(),
|
||||
))
|
||||
|
@ -40,32 +40,6 @@ impl InferredType {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VirtualStorage<T> {
|
||||
storage: HashMap<String, Vec<T>>,
|
||||
}
|
||||
|
||||
impl<T> VirtualStorage<T> {
|
||||
fn set(&mut self, name: String, value: T) {
|
||||
if let Some(list) = self.storage.get_mut(&name) {
|
||||
list.push(value);
|
||||
} else {
|
||||
self.storage.insert(name, vec![value]);
|
||||
};
|
||||
}
|
||||
|
||||
fn get(&self, name: &String) -> Option<&Vec<T>> {
|
||||
self.storage.get(name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for VirtualStorage<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
storage: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::Module {
|
||||
pub fn process(&self) -> mir::Module {
|
||||
let mut imports = Vec::new();
|
||||
@ -115,18 +89,20 @@ impl ast::Block {
|
||||
|
||||
for statement in &self.0 {
|
||||
let (kind, range) = match statement {
|
||||
ast::BlockLevelStatement::Let(s_let) => {
|
||||
let t = s_let.1.infer_return_type().collapse();
|
||||
let inferred = InferredType::Static(t.clone());
|
||||
|
||||
(
|
||||
ast::BlockLevelStatement::Let(s_let) => (
|
||||
mir::StmtKind::Let(
|
||||
mir::VariableReference(t, s_let.0.clone(), s_let.2.into()),
|
||||
s_let.1.process(),
|
||||
mir::VariableReference(
|
||||
s_let
|
||||
.1
|
||||
.map(|t| t.0.into())
|
||||
.unwrap_or(mir::TypeKind::Vague(mir::VagueType::Unknown)),
|
||||
s_let.0.clone(),
|
||||
s_let.3.into(),
|
||||
),
|
||||
s_let.2.process(),
|
||||
),
|
||||
s_let.3,
|
||||
),
|
||||
s_let.2,
|
||||
)
|
||||
}
|
||||
ast::BlockLevelStatement::Import(_) => todo!(),
|
||||
ast::BlockLevelStatement::Expression(e) => (StmtKind::Expression(e.process()), e.1),
|
||||
ast::BlockLevelStatement::Return(_, e) => (StmtKind::Expression(e.process()), e.1),
|
||||
@ -147,13 +123,6 @@ impl ast::Block {
|
||||
meta: self.2.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_return_type(&self) -> InferredType {
|
||||
self.1
|
||||
.as_ref()
|
||||
.map(|(_, expr)| expr.infer_return_type())
|
||||
.unwrap_or(InferredType::Void)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ast::ReturnType> for mir::ReturnKind {
|
||||
@ -201,26 +170,6 @@ impl ast::Expression {
|
||||
|
||||
mir::Expression(kind, self.1.into())
|
||||
}
|
||||
|
||||
fn infer_return_type(&self) -> InferredType {
|
||||
use ast::ExpressionKind::*;
|
||||
match &self.0 {
|
||||
VariableName(name) => InferredType::FromVariable(name.clone()),
|
||||
Literal(lit) => InferredType::Static(lit.mir().as_type()),
|
||||
Binop(_, lhs, rhs) => {
|
||||
InferredType::OneOf(vec![lhs.infer_return_type(), rhs.infer_return_type()])
|
||||
}
|
||||
FunctionCall(fncall) => InferredType::FunctionReturn(fncall.0.clone()),
|
||||
BlockExpr(block) => block.infer_return_type(),
|
||||
IfExpr(exp) => {
|
||||
let mut types = vec![exp.1.infer_return_type()];
|
||||
if let Some(e) = &exp.2 {
|
||||
types.push(e.infer_return_type())
|
||||
}
|
||||
InferredType::OneOf(types)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::BinaryOperator {
|
||||
|
Loading…
Reference in New Issue
Block a user