diff --git a/data/test.lang b/data/test.lang
index 4182d37..e04867f 100644
--- a/data/test.lang
+++ b/data/test.lang
@@ -1,11 +1,24 @@
+struct Test {
+ a: 64,
+ b: 64,
+}
+
fn start() {
println("Helld!");
println("Hello World!!!!!");
thinger();
println("what");
print(tester());
+ let test = Test {
+ a: 10,
+ b: 9,
+ };
arger("a", "b", "c");
- exit(mul(sub(add(5, 9), 1), 3));
+ let z = sub(test.a, 10);
+ exit(add(mul(sub(add(5, test.b), 1), 3), z));
+}
+
+fn structer(test: Test) {
}
fn thinger() {
diff --git a/src/compiler/arch/riscv/compile.rs b/src/compiler/arch/riscv/compile.rs
index fec696a..7f29d1e 100644
--- a/src/compiler/arch/riscv/compile.rs
+++ b/src/compiler/arch/riscv/compile.rs
@@ -88,7 +88,23 @@ pub fn compile(program: &IRLProgram) -> UnlinkedProgram
{
for i in &f.instructions {
irli.push((v.len(), format!("{i:?}")));
match i {
- IRI::Mv { dest, src } => todo!(),
+ IRI::Mv {
+ dest,
+ dest_offset,
+ src,
+ src_offset,
+ } => {
+ let s = align(&f.stack[src]) as u32;
+ mov_mem(
+ &mut v,
+ sp,
+ stack[src] + align(src_offset),
+ sp,
+ stack[dest] + align(dest_offset),
+ t0,
+ s,
+ );
+ }
IRI::Ref { dest, src } => todo!(),
IRI::LoadAddr { dest, offset, src } => {
v.extend([
diff --git a/src/ir/lower/func.rs b/src/ir/lower/func.rs
index 808c0a6..6f1dc9c 100644
--- a/src/ir/lower/func.rs
+++ b/src/ir/lower/func.rs
@@ -16,7 +16,9 @@ pub struct IRLFunction {
pub enum IRLInstruction {
Mv {
dest: VarID,
+ dest_offset: Size,
src: VarID,
+ src_offset: Size,
},
Ref {
dest: VarID,
diff --git a/src/ir/lower/program.rs b/src/ir/lower/program.rs
index ae525f0..efc393b 100644
--- a/src/ir/lower/program.rs
+++ b/src/ir/lower/program.rs
@@ -41,7 +41,9 @@ impl IRLProgram {
}
instrs.push(IRLInstruction::Mv {
dest: dest.id,
+ dest_offset: 0,
src: src.id,
+ src_offset: 0,
});
}
IRUInstruction::Ref { dest, src } => {
@@ -83,7 +85,10 @@ impl IRLProgram {
src: sym,
});
- let sym = builder.anon_ro_data(&(*len as u64).to_le_bytes(), Some(format!("len: {}", len)));
+ let sym = builder.anon_ro_data(
+ &(*len as u64).to_le_bytes(),
+ Some(format!("len: {}", len)),
+ );
instrs.push(IRLInstruction::LoadData {
dest: dest.id,
offset: 8,
@@ -129,6 +134,46 @@ impl IRLProgram {
})
}
IRUInstruction::Ret { src } => instrs.push(IRLInstruction::Ret { src: src.id }),
+ IRUInstruction::Construct { dest, fields } => {
+ if alloc_stack(dest.id) {
+ continue;
+ }
+ let ty = &p.get_var(dest.id).ty;
+ let Type::Concrete(id) = ty else {
+ return Err(format!("Failed to contruct type {}", p.type_name(ty)));
+ };
+ let struc = p.get_struct(*id);
+ for (name, var) in fields {
+ instrs.push(IRLInstruction::Mv {
+ dest: dest.id,
+ src: var.id,
+ dest_offset: struc.fields[name].offset,
+ src_offset: 0,
+ })
+ }
+ }
+ IRUInstruction::Access { dest, src, field } => {
+ if alloc_stack(dest.id) {
+ continue;
+ }
+ let ty = &p.get_var(src.id).ty;
+ let Type::Concrete(id) = ty else {
+ return Err(format!(
+ "Failed to access field of struct {}",
+ p.type_name(ty)
+ ));
+ };
+ let struc = p.get_struct(*id);
+ let Some(field) = struc.fields.get(field) else {
+ return Err(format!("No field {field} in struct {}", p.type_name(ty)));
+ };
+ instrs.push(IRLInstruction::Mv {
+ dest: dest.id,
+ src: src.id,
+ src_offset: field.offset,
+ dest_offset: 0,
+ })
+ }
};
}
builder.write_fn(
diff --git a/src/ir/upper/def.rs b/src/ir/upper/def.rs
index e64bc7c..646990e 100644
--- a/src/ir/upper/def.rs
+++ b/src/ir/upper/def.rs
@@ -1,7 +1,7 @@
-use crate::common::FileSpan;
+use crate::{common::FileSpan, ir::{Len, Size}};
use super::Type;
-use std::fmt::Debug;
+use std::{collections::HashMap, fmt::Debug};
#[derive(Clone)]
pub struct FnDef {
@@ -12,9 +12,16 @@ pub struct FnDef {
}
#[derive(Clone)]
-pub struct TypeDef {
+pub struct StructField {
+ pub ty: Type,
+ pub offset: Len,
+}
+
+#[derive(Clone)]
+pub struct StructDef {
pub name: String,
- pub args: usize,
+ pub fields: HashMap,
+ pub size: Size,
pub origin: Origin,
}
diff --git a/src/ir/upper/func.rs b/src/ir/upper/func.rs
index 2e5af42..2ad9fa6 100644
--- a/src/ir/upper/func.rs
+++ b/src/ir/upper/func.rs
@@ -1,6 +1,8 @@
-use std::fmt::Write;
+use std::{collections::HashMap, fmt::Write};
-use super::{arch::riscv64::RV64Instruction, inst::VarInst, DataID, FnID, IRUInstrInst, Type, VarID};
+use super::{
+ arch::riscv64::RV64Instruction, inst::VarInst, DataID, FnID, IRUInstrInst, Type, VarID,
+};
use crate::{common::FileSpan, compiler::arch::riscv::Reg, util::Padder};
pub struct IRUFunction {
@@ -31,6 +33,11 @@ pub enum IRUInstruction {
dest: VarInst,
src: FnID,
},
+ Access {
+ dest: VarInst,
+ src: VarInst,
+ field: String,
+ },
Call {
dest: VarInst,
f: VarInst,
@@ -43,6 +50,10 @@ pub enum IRUInstruction {
Ret {
src: VarInst,
},
+ Construct {
+ dest: VarInst,
+ fields: HashMap,
+ },
}
pub struct IRInstructions {
@@ -84,6 +95,8 @@ impl std::fmt::Debug for IRUInstruction {
} => write!(f, "{dest:?} <- {func:?}({args:?})"),
Self::AsmBlock { args, instructions } => write!(f, "asm {args:?} {instructions:#?}"),
Self::Ret { src } => f.debug_struct("Ret").field("src", src).finish(),
+ Self::Construct { dest, fields } => write!(f, "{dest:?} <- {fields:?}"),
+ Self::Access { dest, src, field } => write!(f, "{dest:?} <- {src:?}.{field}"),
}
}
}
diff --git a/src/ir/upper/program.rs b/src/ir/upper/program.rs
index ebf232d..86c5d12 100644
--- a/src/ir/upper/program.rs
+++ b/src/ir/upper/program.rs
@@ -11,7 +11,7 @@ use super::{inst::VarInst, *};
pub struct IRUProgram {
pub fn_defs: Vec,
pub var_defs: Vec,
- pub type_defs: Vec,
+ pub type_defs: Vec,
pub data_defs: Vec,
pub fns: Vec