Refactor indexing/accessing a bit, no mutability
This commit is contained in:
parent
4ad871ff3d
commit
3870b421a9
@ -487,7 +487,7 @@ impl InstructionHolder {
|
|||||||
|
|
||||||
let mut llvm_indices: Vec<_> = indices
|
let mut llvm_indices: Vec<_> = indices
|
||||||
.iter()
|
.iter()
|
||||||
.map(|idx| ConstValue::U32(*idx).as_llvm(module))
|
.map(|idx_elem| module.values.get(idx_elem).unwrap().value_ref)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
LLVMBuildGEP2(
|
LLVMBuildGEP2(
|
||||||
|
@ -128,7 +128,7 @@ impl Debug for Instr {
|
|||||||
instruction_value,
|
instruction_value,
|
||||||
&items
|
&items
|
||||||
.iter()
|
.iter()
|
||||||
.map(|i| i.to_string())
|
.map(|expr| format!("{:?}", expr))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", "),
|
.join(", "),
|
||||||
),
|
),
|
||||||
|
@ -226,7 +226,7 @@ pub enum Instr {
|
|||||||
Load(InstructionValue, Type),
|
Load(InstructionValue, Type),
|
||||||
Store(InstructionValue, InstructionValue),
|
Store(InstructionValue, InstructionValue),
|
||||||
ArrayAlloca(Type, u32),
|
ArrayAlloca(Type, u32),
|
||||||
GetElemPtr(InstructionValue, Vec<u32>),
|
GetElemPtr(InstructionValue, Vec<InstructionValue>),
|
||||||
GetStructElemPtr(InstructionValue, u32),
|
GetStructElemPtr(InstructionValue, u32),
|
||||||
|
|
||||||
/// Integer Comparison
|
/// Integer Comparison
|
||||||
|
@ -44,8 +44,10 @@ pub enum ExpressionKind {
|
|||||||
VariableName(String),
|
VariableName(String),
|
||||||
Literal(Literal),
|
Literal(Literal),
|
||||||
Array(Vec<Expression>),
|
Array(Vec<Expression>),
|
||||||
ArrayIndex(Box<Expression>, u64),
|
/// Array-indexed, e.g. <expr>[<expr>]
|
||||||
StructIndex(Box<Expression>, String),
|
Indexed(Box<Expression>, Box<Expression>),
|
||||||
|
/// Struct-accessed, e.g. <expr>.<expr>
|
||||||
|
Accessed(Box<Expression>, String),
|
||||||
Binop(BinaryOperator, Box<Expression>, Box<Expression>),
|
Binop(BinaryOperator, Box<Expression>, Box<Expression>),
|
||||||
FunctionCall(Box<FunctionCallExpression>),
|
FunctionCall(Box<FunctionCallExpression>),
|
||||||
BlockExpr(Box<Block>),
|
BlockExpr(Box<Block>),
|
||||||
|
@ -136,15 +136,15 @@ impl Parse for PrimaryExpression {
|
|||||||
|
|
||||||
while let Ok(index) = stream.parse::<ValueIndex>() {
|
while let Ok(index) = stream.parse::<ValueIndex>() {
|
||||||
match index {
|
match index {
|
||||||
ValueIndex::Array(ArrayValueIndex(idx)) => {
|
ValueIndex::Array(ArrayValueIndex(idx_expr)) => {
|
||||||
expr = Expression(
|
expr = Expression(
|
||||||
ExpressionKind::ArrayIndex(Box::new(expr), idx),
|
ExpressionKind::Indexed(Box::new(expr), Box::new(idx_expr)),
|
||||||
stream.get_range().unwrap(),
|
stream.get_range().unwrap(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ValueIndex::Struct(StructValueIndex(name)) => {
|
ValueIndex::Struct(StructValueIndex(name)) => {
|
||||||
expr = Expression(
|
expr = Expression(
|
||||||
ExpressionKind::StructIndex(Box::new(expr), name),
|
ExpressionKind::Accessed(Box::new(expr), name),
|
||||||
stream.get_range().unwrap(),
|
stream.get_range().unwrap(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -428,16 +428,10 @@ impl Parse for VariableReference {
|
|||||||
while let Ok(val) = stream.parse::<ValueIndex>() {
|
while let Ok(val) = stream.parse::<ValueIndex>() {
|
||||||
match val {
|
match val {
|
||||||
ValueIndex::Array(ArrayValueIndex(idx)) => {
|
ValueIndex::Array(ArrayValueIndex(idx)) => {
|
||||||
var_ref = VariableReference(
|
todo!();
|
||||||
VariableReferenceKind::ArrayIndex(Box::new(var_ref), idx),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
ValueIndex::Struct(StructValueIndex(name)) => {
|
ValueIndex::Struct(StructValueIndex(name)) => {
|
||||||
var_ref = VariableReference(
|
todo!();
|
||||||
VariableReferenceKind::StructIndex(Box::new(var_ref), name),
|
|
||||||
stream.get_range().unwrap(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -515,18 +509,15 @@ impl Parse for ValueIndex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ArrayValueIndex(u64);
|
pub struct ArrayValueIndex(Expression);
|
||||||
|
|
||||||
impl Parse for ArrayValueIndex {
|
impl Parse for ArrayValueIndex {
|
||||||
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
||||||
stream.expect(Token::BracketOpen)?;
|
stream.expect(Token::BracketOpen)?;
|
||||||
if let Some(Token::DecimalValue(idx)) = stream.next() {
|
let expr = stream.parse()?;
|
||||||
stream.expect(Token::BracketClose)?;
|
stream.expect(Token::BracketClose)?;
|
||||||
Ok(ArrayValueIndex(idx))
|
Ok(ArrayValueIndex(expr))
|
||||||
} else {
|
|
||||||
return Err(stream.expected_err("array index (number)")?);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,10 +224,10 @@ impl ast::Expression {
|
|||||||
ast::ExpressionKind::Array(expressions) => {
|
ast::ExpressionKind::Array(expressions) => {
|
||||||
mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect())
|
mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect())
|
||||||
}
|
}
|
||||||
ast::ExpressionKind::ArrayIndex(expression, idx) => mir::ExprKind::ArrayIndex(
|
ast::ExpressionKind::Indexed(expression, idx_expr) => mir::ExprKind::Indexed(
|
||||||
Box::new(expression.process()),
|
Box::new(expression.process()),
|
||||||
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||||
*idx,
|
Box::new(idx_expr.process()),
|
||||||
),
|
),
|
||||||
ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct(
|
ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct(
|
||||||
struct_init.name.clone(),
|
struct_init.name.clone(),
|
||||||
@ -237,7 +237,7 @@ impl ast::Expression {
|
|||||||
.map(|(n, e)| (n.clone(), e.process()))
|
.map(|(n, e)| (n.clone(), e.process()))
|
||||||
.collect(),
|
.collect(),
|
||||||
),
|
),
|
||||||
ast::ExpressionKind::StructIndex(expression, name) => mir::ExprKind::StructIndex(
|
ast::ExpressionKind::Accessed(expression, name) => mir::ExprKind::Accessed(
|
||||||
Box::new(expression.process()),
|
Box::new(expression.process()),
|
||||||
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||||
name.clone(),
|
name.clone(),
|
||||||
|
@ -9,7 +9,7 @@ use reid_lib::{
|
|||||||
|
|
||||||
use crate::mir::{
|
use crate::mir::{
|
||||||
self, types::ReturnType, IndexedVariableReference, NamedVariableRef, StructField, StructType,
|
self, types::ReturnType, IndexedVariableReference, NamedVariableRef, StructField, StructType,
|
||||||
TypeDefinitionKind, TypeKind,
|
TypeDefinitionKind, TypeKind, VagueLiteral,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Context that contains all of the given modules as complete codegenerated
|
/// Context that contains all of the given modules as complete codegenerated
|
||||||
@ -415,11 +415,12 @@ impl mir::Expression {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::ExprKind::ArrayIndex(expression, val_t, idx) => {
|
mir::ExprKind::Indexed(expression, val_t, idx_expr) => {
|
||||||
let array = expression.codegen(scope)?;
|
let array = expression.codegen(scope)?;
|
||||||
|
let idx = idx_expr.codegen(scope)?;
|
||||||
let ptr = scope
|
let ptr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::GetElemPtr(array, vec![*idx as u32]))
|
.build(Instr::GetElemPtr(array, vec![idx]))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
@ -451,17 +452,21 @@ impl mir::Expression {
|
|||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
for (i, instr) in instr_list.iter().enumerate() {
|
for (index, instr) in instr_list.iter().enumerate() {
|
||||||
|
let index_expr = scope
|
||||||
|
.block
|
||||||
|
.build(Instr::Constant(ConstValue::U32(index as u32)))
|
||||||
|
.unwrap();
|
||||||
let ptr = scope
|
let ptr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::GetElemPtr(array, vec![i as u32]))
|
.build(Instr::GetElemPtr(array, vec![index_expr]))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
scope.block.build(Instr::Store(ptr, *instr)).unwrap();
|
scope.block.build(Instr::Store(ptr, *instr)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(array)
|
Some(array)
|
||||||
}
|
}
|
||||||
mir::ExprKind::StructIndex(expression, type_kind, field) => {
|
mir::ExprKind::Accessed(expression, type_kind, field) => {
|
||||||
let struct_val = expression.codegen(scope)?;
|
let struct_val = expression.codegen(scope)?;
|
||||||
|
|
||||||
let struct_ty = expression.return_type().ok()?.1.known().ok()?;
|
let struct_ty = expression.return_type().ok()?.1.known().ok()?;
|
||||||
@ -521,29 +526,30 @@ impl IndexedVariableReference {
|
|||||||
mir::IndexedVariableReferenceKind::ArrayIndex(inner, idx) => {
|
mir::IndexedVariableReferenceKind::ArrayIndex(inner, idx) => {
|
||||||
let inner_stack_val = inner.get_stack_value(scope, true)?;
|
let inner_stack_val = inner.get_stack_value(scope, true)?;
|
||||||
|
|
||||||
let mut gep_instr = scope
|
todo!();
|
||||||
.block
|
// let mut gep_instr = scope
|
||||||
.build(Instr::GetElemPtr(
|
// .block
|
||||||
unsafe { *inner_stack_val.0.get_instr() },
|
// .build(Instr::GetElemPtr(
|
||||||
vec![*idx as u32],
|
// unsafe { *inner_stack_val.0.get_instr() },
|
||||||
))
|
// vec![*idx as u32],
|
||||||
.unwrap();
|
// ))
|
||||||
|
// .unwrap();
|
||||||
|
|
||||||
match &inner_stack_val.1 {
|
// match &inner_stack_val.1 {
|
||||||
Type::Ptr(inner_ty) => {
|
// Type::Ptr(inner_ty) => {
|
||||||
if load_after_gep {
|
// if load_after_gep {
|
||||||
gep_instr = scope
|
// gep_instr = scope
|
||||||
.block
|
// .block
|
||||||
.build(Instr::Load(gep_instr, *inner_ty.clone()))
|
// .build(Instr::Load(gep_instr, *inner_ty.clone()))
|
||||||
.unwrap()
|
// .unwrap()
|
||||||
}
|
// }
|
||||||
Some(StackValue(
|
// Some(StackValue(
|
||||||
inner_stack_val.0.with_instr(gep_instr),
|
// inner_stack_val.0.with_instr(gep_instr),
|
||||||
*inner_ty.clone(),
|
// *inner_ty.clone(),
|
||||||
))
|
// ))
|
||||||
}
|
// }
|
||||||
_ => panic!("Tried to codegen indexing a non-indexable value!"),
|
// _ => panic!("Tried to codegen indexing a non-indexable value!"),
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
mir::IndexedVariableReferenceKind::StructIndex(inner, field) => {
|
mir::IndexedVariableReferenceKind::StructIndex(inner, field) => {
|
||||||
let inner_stack_val = inner.get_stack_value(scope, true)?;
|
let inner_stack_val = inner.get_stack_value(scope, true)?;
|
||||||
@ -647,7 +653,7 @@ impl mir::Literal {
|
|||||||
mir::Literal::U128(val) => ConstValue::U128(val),
|
mir::Literal::U128(val) => ConstValue::U128(val),
|
||||||
mir::Literal::Bool(val) => ConstValue::Bool(val),
|
mir::Literal::Bool(val) => ConstValue::Bool(val),
|
||||||
mir::Literal::String(val) => ConstValue::StringPtr(val.clone()),
|
mir::Literal::String(val) => ConstValue::StringPtr(val.clone()),
|
||||||
mir::Literal::Vague(_) => panic!("Got vague literal!"),
|
mir::Literal::Vague(VagueLiteral::Number(val)) => ConstValue::I32(val as i32),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,10 +164,10 @@ impl Display for ExprKind {
|
|||||||
ExprKind::FunctionCall(fc) => Display::fmt(fc, f),
|
ExprKind::FunctionCall(fc) => Display::fmt(fc, f),
|
||||||
ExprKind::If(if_exp) => Display::fmt(&if_exp, f),
|
ExprKind::If(if_exp) => Display::fmt(&if_exp, f),
|
||||||
ExprKind::Block(block) => Display::fmt(block, f),
|
ExprKind::Block(block) => Display::fmt(block, f),
|
||||||
ExprKind::ArrayIndex(expression, elem_ty, idx) => {
|
ExprKind::Indexed(expression, elem_ty, idx_expr) => {
|
||||||
Display::fmt(&expression, f)?;
|
Display::fmt(&expression, f)?;
|
||||||
write!(f, "<{}>", elem_ty)?;
|
write!(f, "<{}>", elem_ty)?;
|
||||||
write_index(f, *idx)
|
write_index(f, idx_expr)
|
||||||
}
|
}
|
||||||
ExprKind::Array(expressions) => {
|
ExprKind::Array(expressions) => {
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
@ -203,7 +203,7 @@ impl Display for ExprKind {
|
|||||||
}
|
}
|
||||||
f.write_char('}')
|
f.write_char('}')
|
||||||
}
|
}
|
||||||
ExprKind::StructIndex(expression, type_kind, name) => {
|
ExprKind::Accessed(expression, type_kind, name) => {
|
||||||
Display::fmt(&expression, f)?;
|
Display::fmt(&expression, f)?;
|
||||||
write_access(f, name)?;
|
write_access(f, name)?;
|
||||||
write!(f, "<{}>", type_kind)
|
write!(f, "<{}>", type_kind)
|
||||||
@ -309,7 +309,7 @@ impl Display for Metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_index(f: &mut std::fmt::Formatter<'_>, idx: u64) -> std::fmt::Result {
|
fn write_index(f: &mut std::fmt::Formatter<'_>, idx: impl std::fmt::Display) -> std::fmt::Result {
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
Display::fmt(&idx, f)?;
|
Display::fmt(&idx, f)?;
|
||||||
f.write_char(']')
|
f.write_char(']')
|
||||||
|
@ -192,8 +192,8 @@ pub struct Import(pub Vec<String>, pub Metadata);
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ExprKind {
|
pub enum ExprKind {
|
||||||
Variable(NamedVariableRef),
|
Variable(NamedVariableRef),
|
||||||
ArrayIndex(Box<Expression>, TypeKind, u64),
|
Indexed(Box<Expression>, TypeKind, Box<Expression>),
|
||||||
StructIndex(Box<Expression>, TypeKind, String),
|
Accessed(Box<Expression>, TypeKind, String),
|
||||||
Array(Vec<Expression>),
|
Array(Vec<Expression>),
|
||||||
Struct(String, Vec<(String, Expression)>),
|
Struct(String, Vec<(String, Expression)>),
|
||||||
Literal(Literal),
|
Literal(Literal),
|
||||||
|
@ -504,7 +504,7 @@ impl Expression {
|
|||||||
Ok((_, ty)) => Ok(ty),
|
Ok((_, ty)) => Ok(ty),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
},
|
},
|
||||||
ExprKind::ArrayIndex(expression, elem_ty, idx) => {
|
ExprKind::Indexed(expression, elem_ty, idx) => {
|
||||||
// Try to unwrap hint type from array if possible
|
// Try to unwrap hint type from array if possible
|
||||||
let hint_t = hint_t.map(|t| match t {
|
let hint_t = hint_t.map(|t| match t {
|
||||||
TypeKind::Array(type_kind, _) => &type_kind,
|
TypeKind::Array(type_kind, _) => &type_kind,
|
||||||
@ -513,9 +513,6 @@ impl Expression {
|
|||||||
|
|
||||||
let expr_t = expression.typecheck(state, hints, hint_t)?;
|
let expr_t = expression.typecheck(state, hints, hint_t)?;
|
||||||
if let TypeKind::Array(inferred_ty, len) = expr_t {
|
if let TypeKind::Array(inferred_ty, len) = expr_t {
|
||||||
if len <= *idx {
|
|
||||||
return Err(ErrorKind::IndexOutOfBounds(*idx, len));
|
|
||||||
}
|
|
||||||
let ty = state.or_else(
|
let ty = state.or_else(
|
||||||
elem_ty.resolve_ref(hints).collapse_into(&inferred_ty),
|
elem_ty.resolve_ref(hints).collapse_into(&inferred_ty),
|
||||||
TypeKind::Vague(Vague::Unknown),
|
TypeKind::Vague(Vague::Unknown),
|
||||||
@ -564,7 +561,7 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::StructIndex(expression, type_kind, field_name) => {
|
ExprKind::Accessed(expression, type_kind, field_name) => {
|
||||||
// Resolve expected type
|
// Resolve expected type
|
||||||
let expected_ty = type_kind.resolve_ref(hints);
|
let expected_ty = type_kind.resolve_ref(hints);
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ impl Expression {
|
|||||||
ReturnKind::Soft => Ok(block_ref.1),
|
ReturnKind::Soft => Ok(block_ref.1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::ArrayIndex(expression, index_ty, _) => {
|
ExprKind::Indexed(expression, index_ty, _) => {
|
||||||
let expr_ty = expression.infer_types(state, type_refs)?;
|
let expr_ty = expression.infer_types(state, type_refs)?;
|
||||||
|
|
||||||
// Check that the resolved type is at least an array, no
|
// Check that the resolved type is at least an array, no
|
||||||
@ -302,7 +302,7 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::StructIndex(expression, type_kind, field_name) => {
|
ExprKind::Accessed(expression, type_kind, field_name) => {
|
||||||
let expr_ty = expression.infer_types(state, type_refs)?;
|
let expr_ty = expression.infer_types(state, type_refs)?;
|
||||||
|
|
||||||
// Check that the resolved type is at least a struct, no
|
// Check that the resolved type is at least a struct, no
|
||||||
|
@ -107,7 +107,7 @@ impl ReturnType for Expression {
|
|||||||
Block(block) => block.return_type(),
|
Block(block) => block.return_type(),
|
||||||
FunctionCall(fcall) => fcall.return_type(),
|
FunctionCall(fcall) => fcall.return_type(),
|
||||||
If(expr) => expr.return_type(),
|
If(expr) => expr.return_type(),
|
||||||
ArrayIndex(expression, _, _) => {
|
Indexed(expression, _, _) => {
|
||||||
let expr_type = expression.return_type()?;
|
let expr_type = expression.return_type()?;
|
||||||
if let (_, TypeKind::Array(elem_ty, _)) = expr_type {
|
if let (_, TypeKind::Array(elem_ty, _)) = expr_type {
|
||||||
Ok((ReturnKind::Soft, *elem_ty))
|
Ok((ReturnKind::Soft, *elem_ty))
|
||||||
@ -126,7 +126,7 @@ impl ReturnType for Expression {
|
|||||||
TypeKind::Array(Box::new(first.1), expressions.len() as u64),
|
TypeKind::Array(Box::new(first.1), expressions.len() as u64),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
StructIndex(_, type_kind, _) => Ok((ReturnKind::Soft, type_kind.clone())),
|
Accessed(_, type_kind, _) => Ok((ReturnKind::Soft, type_kind.clone())),
|
||||||
Struct(name, _) => Ok((ReturnKind::Soft, TypeKind::CustomType(name.clone()))),
|
Struct(name, _) => Ok((ReturnKind::Soft, TypeKind::CustomType(name.clone()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ fn main() -> u32 {
|
|||||||
second: [6, 3, 17, 8],
|
second: [6, 3, 17, 8],
|
||||||
}];
|
}];
|
||||||
|
|
||||||
value[0].second[2] = 99;
|
// value[0].second[2] = 99;
|
||||||
|
|
||||||
return value[0].second[2];
|
return value[0].second[2];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user