Continue progress, make set-statements as todos for later
This commit is contained in:
parent
10cf9341c5
commit
a18a5b4199
@ -133,11 +133,11 @@ pub struct Block(
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VariableReference(VariableReferenceKind, TokenRange);
|
||||
pub struct VariableReference(pub VariableReferenceKind, pub TokenRange);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum VariableReferenceKind {
|
||||
Name(String),
|
||||
Name(String, TokenRange),
|
||||
Index(Box<VariableReference>, u64),
|
||||
}
|
||||
|
||||
|
@ -384,7 +384,7 @@ impl Parse for VariableReference {
|
||||
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
||||
if let Some(Token::Identifier(ident)) = stream.next() {
|
||||
let mut var_ref = VariableReference(
|
||||
VariableReferenceKind::Name(ident),
|
||||
VariableReferenceKind::Name(ident, stream.get_one_token_range()),
|
||||
stream.get_range().unwrap(),
|
||||
);
|
||||
|
||||
|
@ -76,14 +76,7 @@ impl ast::Block {
|
||||
s_let.4,
|
||||
),
|
||||
ast::BlockLevelStatement::Set(var_ref, expression, range) => (
|
||||
StmtKind::Set(
|
||||
NamedVariableRef(
|
||||
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||
todo!(), // was name.clone()
|
||||
(*range).into(),
|
||||
),
|
||||
expression.process(),
|
||||
),
|
||||
StmtKind::Set(var_ref.process(), expression.process()),
|
||||
*range,
|
||||
),
|
||||
ast::BlockLevelStatement::Import { _i } => todo!(),
|
||||
@ -119,16 +112,25 @@ impl From<ast::ReturnType> for mir::ReturnKind {
|
||||
|
||||
impl ast::VariableReference {
|
||||
fn process(&self) -> mir::IndexedVariableReference {
|
||||
match &self.0 {
|
||||
ast::VariableReferenceKind::Name(name) => {
|
||||
mir::IndexedVariableReference::Named(NamedVariableRef(
|
||||
mir::IndexedVariableReference {
|
||||
kind: self.0.process(),
|
||||
meta: self.1.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::VariableReferenceKind {
|
||||
fn process(&self) -> mir::IndexedVariableReferenceKind {
|
||||
match &self {
|
||||
ast::VariableReferenceKind::Name(name, range) => {
|
||||
mir::IndexedVariableReferenceKind::Named(NamedVariableRef(
|
||||
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||
name.clone(),
|
||||
self.1.into(),
|
||||
(*range).into(),
|
||||
))
|
||||
}
|
||||
ast::VariableReferenceKind::Index(var_ref, idx) => {
|
||||
mir::IndexedVariableReference::Index(Box::new(var_ref.process()), *idx)
|
||||
mir::IndexedVariableReferenceKind::Index(Box::new(var_ref.process()), *idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -166,7 +168,9 @@ impl ast::Expression {
|
||||
};
|
||||
mir::ExprKind::If(mir::IfExpression(Box::new(cond), then_block, else_block))
|
||||
}
|
||||
ast::ExpressionKind::Array(expressions) => todo!("process for array expression"),
|
||||
ast::ExpressionKind::Array(expressions) => {
|
||||
mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect())
|
||||
}
|
||||
ast::ExpressionKind::Index(expression, idx) => {
|
||||
mir::ExprKind::Index(Box::new(expression.process()), *idx)
|
||||
}
|
||||
|
@ -178,19 +178,20 @@ impl mir::Statement {
|
||||
None
|
||||
}
|
||||
mir::StmtKind::Set(var, val) => {
|
||||
if let Some(StackValue(kind, _)) = scope.stack_values.get(&var.1).cloned() {
|
||||
match kind {
|
||||
StackValueKind::Immutable(_) => {
|
||||
panic!("Tried to mutate an immutable variable")
|
||||
}
|
||||
StackValueKind::Mutable(ptr) => {
|
||||
let expression = val.codegen(scope).unwrap();
|
||||
Some(scope.block.build(Instr::Store(ptr, expression)).unwrap())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic!("")
|
||||
}
|
||||
todo!("Re-think how set needs to work with arrays");
|
||||
// if let Some(StackValue(kind, _)) = scope.stack_values.get(&var.1).cloned() {
|
||||
// match kind {
|
||||
// StackValueKind::Immutable(_) => {
|
||||
// panic!("Tried to mutate an immutable variable")
|
||||
// }
|
||||
// StackValueKind::Mutable(ptr) => {
|
||||
// let expression = val.codegen(scope).unwrap();
|
||||
// Some(scope.block.build(Instr::Store(ptr, expression)).unwrap())
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// panic!("")
|
||||
// }
|
||||
}
|
||||
// mir::StmtKind::If(if_expression) => if_expression.codegen(scope),
|
||||
mir::StmtKind::Import(_) => todo!(),
|
||||
|
@ -180,9 +180,9 @@ impl Display for NamedVariableRef {
|
||||
|
||||
impl Display for IndexedVariableReference {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
IndexedVariableReference::Named(name) => Display::fmt(name, f),
|
||||
IndexedVariableReference::Index(variable_reference_kind, idx) => {
|
||||
match &self.kind {
|
||||
IndexedVariableReferenceKind::Named(name) => Display::fmt(name, f),
|
||||
IndexedVariableReferenceKind::Index(variable_reference_kind, idx) => {
|
||||
Display::fmt(&variable_reference_kind, f)?;
|
||||
write_index(f, *idx)
|
||||
}
|
||||
|
@ -273,7 +273,14 @@ pub struct Block {
|
||||
#[derive(Debug)]
|
||||
pub struct Statement(pub StmtKind, pub Metadata);
|
||||
|
||||
pub enum IndexedVariableReference {
|
||||
#[derive(Debug)]
|
||||
pub struct IndexedVariableReference {
|
||||
pub kind: IndexedVariableReferenceKind,
|
||||
pub meta: Metadata,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum IndexedVariableReferenceKind {
|
||||
Named(NamedVariableRef),
|
||||
Index(Box<IndexedVariableReference>, u64),
|
||||
}
|
||||
@ -282,7 +289,7 @@ pub enum IndexedVariableReference {
|
||||
pub enum StmtKind {
|
||||
/// Variable name++mutability+type, evaluation
|
||||
Let(NamedVariableRef, bool, Expression),
|
||||
Set(NamedVariableRef, Expression),
|
||||
Set(IndexedVariableReference, Expression),
|
||||
Import(Import),
|
||||
Expression(Expression),
|
||||
}
|
||||
|
@ -165,40 +165,41 @@ impl Block {
|
||||
None
|
||||
}
|
||||
StmtKind::Set(variable_reference, expression) => {
|
||||
if let Some(var) = state.scope.variables.get(&variable_reference.1).cloned() {
|
||||
// Typecheck expression and coerce to variable type
|
||||
let res = expression.typecheck(&mut state, &hints, Some(&var.ty));
|
||||
todo!("Re-think how set needs to work with arrays")
|
||||
// if let Some(var) = state.scope.variables.get(&variable_reference.1).cloned() {
|
||||
// // Typecheck expression and coerce to variable type
|
||||
// let res = expression.typecheck(&mut state, &hints, Some(&var.ty));
|
||||
|
||||
// If expression resolution itself was erronous, resolve as
|
||||
// Unknown.
|
||||
let expr_ty = state.or_else(res, Vague(Unknown), expression.1);
|
||||
// // If expression resolution itself was erronous, resolve as
|
||||
// // Unknown.
|
||||
// let expr_ty = state.or_else(res, Vague(Unknown), expression.1);
|
||||
|
||||
// Make sure the expression and variable type to really
|
||||
// be the same
|
||||
let res_t = state.or_else(
|
||||
expr_ty.collapse_into(&variable_reference.0.resolve_hinted(&hints)),
|
||||
Vague(Unknown),
|
||||
variable_reference.2 + expression.1,
|
||||
);
|
||||
// // Make sure the expression and variable type to really
|
||||
// // be the same
|
||||
// let res_t = state.or_else(
|
||||
// expr_ty.collapse_into(&variable_reference.0.resolve_hinted(&hints)),
|
||||
// Vague(Unknown),
|
||||
// variable_reference.2 + expression.1,
|
||||
// );
|
||||
|
||||
// Update typing to be more accurate
|
||||
variable_reference.0 = res_t;
|
||||
// // Update typing to be more accurate
|
||||
// variable_reference.0 = res_t;
|
||||
|
||||
if !var.mutable {
|
||||
state.ok::<_, Infallible>(
|
||||
Err(ErrorKind::VariableNotMutable(variable_reference.1.clone())),
|
||||
variable_reference.2,
|
||||
);
|
||||
}
|
||||
// if !var.mutable {
|
||||
// state.ok::<_, Infallible>(
|
||||
// Err(ErrorKind::VariableNotMutable(variable_reference.1.clone())),
|
||||
// variable_reference.2,
|
||||
// );
|
||||
// }
|
||||
|
||||
None
|
||||
} else {
|
||||
state.ok::<_, Infallible>(
|
||||
Err(ErrorKind::VariableNotDefined(variable_reference.1.clone())),
|
||||
variable_reference.2,
|
||||
);
|
||||
None
|
||||
}
|
||||
// None
|
||||
// } else {
|
||||
// state.ok::<_, Infallible>(
|
||||
// Err(ErrorKind::VariableNotDefined(variable_reference.1.clone())),
|
||||
// variable_reference.2,
|
||||
// );
|
||||
// None
|
||||
// }
|
||||
}
|
||||
StmtKind::Import(_) => todo!(), // TODO
|
||||
StmtKind::Expression(expression) => {
|
||||
|
@ -111,23 +111,24 @@ impl Block {
|
||||
}
|
||||
}
|
||||
StmtKind::Set(var, expr) => {
|
||||
// Get the TypeRef for this variable declaration
|
||||
let var_ref = inner_hints.find_hint(&var.1);
|
||||
todo!("Re-think how set needs to work with arrays")
|
||||
// // Get the TypeRef for this variable declaration
|
||||
// let var_ref = inner_hints.find_hint(&var.1);
|
||||
|
||||
// If ok, update the MIR type to this TypeRef
|
||||
if let Some((_, var_ref)) = &var_ref {
|
||||
var.0 = var_ref.as_type()
|
||||
}
|
||||
// // If ok, update the MIR type to this TypeRef
|
||||
// if let Some((_, var_ref)) = &var_ref {
|
||||
// var.0 = var_ref.as_type()
|
||||
// }
|
||||
|
||||
// Infer hints for the expression itself
|
||||
let inferred = expr.infer_types(&mut state, &inner_hints);
|
||||
let expr_ty_ref = state.ok(inferred, expr.1);
|
||||
// // Infer hints for the expression itself
|
||||
// let inferred = expr.infer_types(&mut state, &inner_hints);
|
||||
// let expr_ty_ref = state.ok(inferred, expr.1);
|
||||
|
||||
// Try to narrow the variable type declaration with the
|
||||
// expression
|
||||
if let (Some((_, mut var_ref)), Some(expr_ty_ref)) = (var_ref, expr_ty_ref) {
|
||||
var_ref.narrow(&expr_ty_ref);
|
||||
}
|
||||
// // Try to narrow the variable type declaration with the
|
||||
// // expression
|
||||
// if let (Some((_, mut var_ref)), Some(expr_ty_ref)) = (var_ref, expr_ty_ref) {
|
||||
// var_ref.narrow(&expr_ty_ref);
|
||||
// }
|
||||
}
|
||||
StmtKind::Import(_) => todo!(),
|
||||
StmtKind::Expression(expr) => {
|
||||
|
@ -1,3 +1,5 @@
|
||||
use crate::ast::VariableReference;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -64,7 +66,7 @@ impl ReturnType for Statement {
|
||||
),
|
||||
Set(var, expr) => if_hard(
|
||||
expr.return_type()?,
|
||||
Err(ReturnTypeOther::Set(var.2 + expr.1)),
|
||||
Err(ReturnTypeOther::Set(var.meta + expr.1)),
|
||||
),
|
||||
Import(_) => todo!(),
|
||||
Expression(expression) => expression.return_type(),
|
||||
|
@ -153,6 +153,13 @@ impl<'a, 'b> TokenStream<'a, 'b> {
|
||||
end: self.position,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_one_token_range(&self) -> TokenRange {
|
||||
TokenRange {
|
||||
start: self.position - 1,
|
||||
end: self.position,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TokenStream<'_, '_> {
|
||||
|
Loading…
Reference in New Issue
Block a user