diff --git a/README.md b/README.md
index 7fb22bb..9f31e6a 100644
--- a/README.md
+++ b/README.md
@@ -19,3 +19,4 @@ todo:
- iterators?
- borrow checking
- basic optimization: use registers, remove temp var moves
+- Cow str
diff --git a/data/test.lang b/data/test.lang
index 4a56d5d..fd635ae 100644
--- a/data/test.lang
+++ b/data/test.lang
@@ -31,7 +31,7 @@ fn start() {
};
println("after");
print(tester());
- let test = Test {
+ let test: Test = Test {
a: 10,
b: 4,
c: 0,
@@ -59,7 +59,7 @@ fn structer(test: Test) {
print_dec(test.c);
println("");
- let test2 = Test2 {
+ let test2: Test2 = Test2 {
a: 3,
b: test,
c: test,
diff --git a/src/compiler/arch/riscv/compile.rs b/src/compiler/arch/riscv/compile.rs
index d14f19c..393207c 100644
--- a/src/compiler/arch/riscv/compile.rs
+++ b/src/compiler/arch/riscv/compile.rs
@@ -4,7 +4,7 @@ use crate::{
compiler::{arch::riscv::Reg, debug::DebugInfo, UnlinkedFunction, UnlinkedProgram},
ir::{
arch::riscv64::{RV64Instruction as AI, RegRef},
- IRLInstruction as IRI, IRLProgram, Len, Size,
+ LInstruction as IRI, LProgram, Len, Size,
},
};
@@ -47,7 +47,7 @@ fn mov_mem(
}
}
-pub fn compile(program: &IRLProgram) -> UnlinkedProgram
{
+pub fn compile(program: &LProgram) -> UnlinkedProgram {
let mut fns = Vec::new();
let mut data = Vec::new();
let mut dbg = DebugInfo::new(program.labels().to_vec());
diff --git a/src/compiler/mod.rs b/src/compiler/mod.rs
index 1db9c44..db94d01 100644
--- a/src/compiler/mod.rs
+++ b/src/compiler/mod.rs
@@ -7,8 +7,8 @@ mod target;
use arch::riscv;
pub use program::*;
-use crate::ir::IRLProgram;
+use crate::ir::LProgram;
-pub fn compile(program: &IRLProgram) -> UnlinkedProgram {
+pub fn compile(program: &LProgram) -> UnlinkedProgram {
arch::riscv::compile(program)
}
diff --git a/src/ir/id.rs b/src/ir/id.rs
index 0b06019..98fd4da 100644
--- a/src/ir/id.rs
+++ b/src/ir/id.rs
@@ -1,46 +1,51 @@
-use std::fmt::Debug;
-
-#[derive(Clone, Copy, Eq, Hash, PartialEq)]
-pub struct StructID(pub usize);
-#[derive(Clone, Copy, Eq, Hash, PartialEq)]
-pub struct VarID(pub usize);
-#[derive(Clone, Copy, Eq, Hash, PartialEq)]
-pub struct FnID(pub usize);
-#[derive(Clone, Copy, Eq, Hash, PartialEq)]
-pub struct DataID(pub usize);
-#[derive(Clone, Copy, Eq, Hash, PartialEq)]
-pub struct FieldID(pub usize);
+use std::{fmt::Debug, marker::PhantomData};
// I had an idea for why these were different... now I don't
pub type Size = u32;
pub type Len = u32;
-impl Debug for VarID {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "var{}", self.0)
+pub struct ID(pub usize, PhantomData);
+
+impl ID {
+ pub fn new(i: usize) -> Self {
+ Self(i, PhantomData)
}
}
-impl Debug for StructID {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "ty{}", self.0)
+pub trait Named {
+ const NAME: &str;
+}
+
+impl From for ID {
+ fn from(value: usize) -> Self {
+ Self(value, PhantomData)
}
}
-impl Debug for FnID {
+impl Debug for ID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "fn{}", self.0)
+ write!(f, "{}{}", K::NAME, self.0)
}
}
-impl Debug for DataID {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "data{}", self.0)
+impl PartialEq for ID {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
}
}
-impl Debug for FieldID {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "field{}", self.0)
+impl Eq for ID {}
+
+impl std::hash::Hash for ID {
+ fn hash(&self, state: &mut H) {
+ self.0.hash(state);
}
}
+
+impl Clone for ID {
+ fn clone(&self) -> Self {
+ Self(self.0.clone(), PhantomData)
+ }
+}
+
+impl Copy for ID {}
diff --git a/src/ir/lower/func.rs b/src/ir/lower/func.rs
index 6e86538..ee6431e 100644
--- a/src/ir/lower/func.rs
+++ b/src/ir/lower/func.rs
@@ -5,7 +5,7 @@ use std::collections::HashMap;
#[derive(Debug)]
pub struct IRLFunction {
- pub instructions: Vec,
+ pub instructions: Vec,
pub stack: HashMap,
pub subvar_map: HashMap,
pub args: Vec<(VarID, Size)>,
@@ -14,7 +14,7 @@ pub struct IRLFunction {
}
#[derive(Debug)]
-pub enum IRLInstruction {
+pub enum LInstruction {
Mv {
dest: VarID,
dest_offset: Size,
@@ -59,7 +59,7 @@ pub enum IRLInstruction {
Mark(Symbol),
}
-impl IRLInstruction {
+impl LInstruction {
pub fn is_ret(&self) -> bool {
matches!(self, Self::Ret { .. })
}
diff --git a/src/ir/lower/program.rs b/src/ir/lower/program.rs
index eada48b..e4b5ed4 100644
--- a/src/ir/lower/program.rs
+++ b/src/ir/lower/program.rs
@@ -1,41 +1,38 @@
use std::collections::HashMap;
-use crate::ir::{AsmBlockArgType, IRUFunction, IRUInstrInst, Size, SymbolSpace, VarOffset};
+use crate::ir::{AsmBlockArgType, UInstrInst, Size, SymbolSpace, UFunc, VarOffset};
use super::{
- IRLFunction, IRLInstruction, IRUInstruction, IRUProgram, Len, Symbol, SymbolSpaceBuilder, Type,
+ IRLFunction, LInstruction, Len, Symbol, SymbolSpaceBuilder, Type, UInstruction, UProgram,
VarID,
};
-pub struct IRLProgram {
+pub struct LProgram {
sym_space: SymbolSpace,
entry: Symbol,
}
// NOTE: there are THREE places here where I specify size (8)
-impl IRLProgram {
- pub fn create(p: &IRUProgram) -> Result {
- let mut start = None;
- for (i, f) in p.iter_fns() {
- if f.name == "start" {
- start = Some(i);
- }
- }
- let start = start.ok_or("no start method found")?;
+impl LProgram {
+ pub fn create(p: &UProgram) -> Result {
+ let start = p
+ .names
+ .lookup::("start")
+ .ok_or("no start method found")?;
let mut ssbuilder = SymbolSpaceBuilder::with_entries(&[start]);
let entry = ssbuilder.func(&start);
while let Some((sym, i)) = ssbuilder.pop_fn() {
let f = p.fns[i.0].as_ref().unwrap();
- let mut fbuilder = IRLFunctionBuilder::new(p, &mut ssbuilder);
+ let mut fbuilder = LFunctionBuilder::new(p, &mut ssbuilder);
for i in &f.instructions {
fbuilder.insert_instr(i);
}
if fbuilder.instrs.last().is_none_or(|i| !i.is_ret()) {
- fbuilder.instrs.push(IRLInstruction::Ret { src: None });
+ fbuilder.instrs.push(LInstruction::Ret { src: None });
}
let res = fbuilder.finish(f);
- ssbuilder.write_fn(sym, res, Some(f.name.clone()));
+ ssbuilder.write_fn(sym, res, Some(p.names.get(i).to_string()));
}
let sym_space = ssbuilder.finish().expect("we failed the mission");
Ok(Self { sym_space, entry })
@@ -46,10 +43,10 @@ impl IRLProgram {
}
}
-pub struct IRLFunctionBuilder<'a> {
- program: &'a IRUProgram,
+pub struct LFunctionBuilder<'a> {
+ program: &'a UProgram,
builder: &'a mut SymbolSpaceBuilder,
- instrs: Vec,
+ instrs: Vec,
stack: HashMap,
subvar_map: HashMap,
makes_call: bool,
@@ -62,8 +59,8 @@ pub struct LoopCtx {
bot: Symbol,
}
-impl<'a> IRLFunctionBuilder<'a> {
- pub fn new(program: &'a IRUProgram, builder: &'a mut SymbolSpaceBuilder) -> Self {
+impl<'a> LFunctionBuilder<'a> {
+ pub fn new(program: &'a UProgram, builder: &'a mut SymbolSpaceBuilder) -> Self {
Self {
instrs: Vec::new(),
stack: HashMap::new(),
@@ -92,50 +89,56 @@ impl<'a> IRLFunctionBuilder<'a> {
self.subvar_map.insert(i, off);
}
}
- pub fn insert_instr(&mut self, i: &IRUInstrInst) -> Option