Skip to content

Commit

Permalink
a bunch
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanWoollett-Light committed Dec 25, 2023
1 parent 6007a33 commit bfd647a
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 86 deletions.
64 changes: 64 additions & 0 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,70 @@ impl std::fmt::Display for Statement {
),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::Def) => match self.arg.as_slice() {
[x] => write!(f, "def {x}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::If(Cmp::Eq)) => match self.arg.as_slice() {
[lhs, rhs] => write!(f, "if {lhs} = {rhs}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::Add) => match self.arg.as_slice() {
[a, b, c] => write!(f, "{a} := {b} + {c}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::Sub) => match self.arg.as_slice() {
[a, b, c] => write!(f, "{a} := {b} - {c}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::Div) => match self.arg.as_slice() {
[a, b, c] => write!(f, "{a} := {b} / {c}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::Mul) => match self.arg.as_slice() {
[a, b, c] => write!(f, "{a} := {b} * {c}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::Or) => match self.arg.as_slice() {
[a, b, c] => write!(f, "{a} := {b} | {c}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::And) => match self.arg.as_slice() {
[a, b, c] => write!(f, "{a} := {b} & {c}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::Xor) => match self.arg.as_slice() {
[a, b, c] => write!(f, "{a} := {b} ^ {c}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::AddAssign) => match self.arg.as_slice() {
[a, b] => write!(f, "{a} += {b}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::SubAssign) => match self.arg.as_slice() {
[a, b] => write!(f, "{a} -= {b}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::DivAssign) => match self.arg.as_slice() {
[a, b] => write!(f, "{a} /= {b}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::MulAssign) => match self.arg.as_slice() {
[a, b] => write!(f, "{a} *= {b}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::OrAssign) => match self.arg.as_slice() {
[a, b] => write!(f, "{a} |= {b}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::AndAssign) => match self.arg.as_slice() {
[a, b] => write!(f, "{a} &= {b}"),
_ => todo!(),
},
Op::Intrinsic(Intrinsic::XorAssign) => match self.arg.as_slice() {
[a, b] => write!(f, "{a} ^= {b}"),
_ => todo!(),
},
x @ _ => todo!("{x:?}"),
}
}
Expand Down
26 changes: 26 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,32 @@ fn display_ast(node: std::ptr::NonNull<crate::ast::NewNode>) -> String {
}
}

#[allow(dead_code)] // This is used for debugging
fn display_ast_addresses(node: std::ptr::NonNull<crate::ast::NewNode>) -> String {
unsafe {
use std::fmt::Write;
let mut stack = vec![(node, 0)];
let mut string = String::new();
while let Some((current, indent)) = stack.pop() {
writeln!(
&mut string,
"{current:?} {}{}",
" ".repeat(indent),
current.as_ref().statement
)
.unwrap();

if let Some(next) = current.as_ref().next {
stack.push((next, indent));
}
if let Some(child) = current.as_ref().child {
stack.push((child, indent + 1));
}
}
string
}
}

#[cfg(test)]
mod tests {
#[cfg(feature = "false")]
Expand Down
133 changes: 51 additions & 82 deletions src/middle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1172,8 +1172,13 @@ pub unsafe fn inline_functions(node: NonNull<NewNode>) -> NonNull<NewNode> {
)];

while let Some((current, mut preceding, next_carry, variable_map)) = stack.pop() {
eprintln!("op: {:?}", &current.as_ref().statement.op);
eprintln!("variable_map: {:?}", variable_map.borrow());
// eprintln!("old ast:\n{}\n", crate::display_ast_addresses(node));
// eprintln!(
// "new ast:\n{}\n",
// first
// .map(|n| crate::display_ast_addresses(n))
// .unwrap_or(String::new())
// );

match current.as_ref().statement.op {
// Function definition
Expand All @@ -1191,7 +1196,6 @@ pub unsafe fn inline_functions(node: NonNull<NewNode>) -> NonNull<NewNode> {

if let Some(mut next) = current.as_ref().next {
next.as_mut().preceding = current.as_ref().preceding;

stack.push((next, preceding, next_carry, variable_map));
}
}
Expand Down Expand Up @@ -1259,7 +1263,15 @@ pub unsafe fn inline_functions(node: NonNull<NewNode>) -> NonNull<NewNode> {
}), ..] => {
// Create new node.
let dst = alloc::alloc(alloc::Layout::new::<NewNode>()).cast::<NewNode>();
ptr::copy(current.as_ptr(), dst, 1);
ptr::write(
dst,
NewNode {
statement: current.as_ref().statement.clone(),
preceding,
child: None,
next: None,
},
);
let mut new = NonNull::new(dst).unwrap();

let [Value::Variable(variable), tail @ ..] =
Expand Down Expand Up @@ -1326,6 +1338,8 @@ pub unsafe fn inline_functions(node: NonNull<NewNode>) -> NonNull<NewNode> {
stack.push((next, Some(Preceding::Previous(new)), None, old_variable_map));
new.as_mut().next = None;
}
debug_assert_eq!(new.as_ref().next, None);
debug_assert_eq!(new.as_ref().child, None);
}
_ => todo!(),
},
Expand Down Expand Up @@ -1359,7 +1373,15 @@ pub unsafe fn inline_functions(node: NonNull<NewNode>) -> NonNull<NewNode> {
[Value::Variable(_), ..] => {
// Create new node.
let dst = alloc::alloc(alloc::Layout::new::<NewNode>()).cast::<NewNode>();
ptr::copy(current.as_ptr(), dst, 1);
ptr::write(
dst,
NewNode {
statement: current.as_ref().statement.clone(),
preceding,
child: None,
next: None,
},
);
let mut new = NonNull::new(dst).unwrap();

let [Value::Variable(variable), tail @ ..] =
Expand Down Expand Up @@ -1423,79 +1445,8 @@ pub unsafe fn inline_functions(node: NonNull<NewNode>) -> NonNull<NewNode> {
stack.push((next, Some(Preceding::Previous(new)), None, old_variable_map));
new.as_mut().next = None;
}
}
_ => todo!(),
},
Op::Syscall(Syscall::Read) => match current.as_ref().statement.arg.as_slice() {
[Value::Variable(_), ..] => {
// TODO Support case where lhs already exists.

// Create new node.
let dst = alloc::alloc(alloc::Layout::new::<NewNode>()).cast::<NewNode>();
ptr::copy(current.as_ptr(), dst, 1);
let mut new = NonNull::new(dst).unwrap();

let [Value::Variable(variable), tail @ ..] =
new.as_mut().statement.arg.as_mut_slice()
else {
unreachable!()
};

// Update new preceding.
match preceding {
Some(Preceding::Parent(mut parent)) => {
debug_assert!(parent.as_ref().child.is_none());
parent.as_mut().child = Some(new);
}
Some(Preceding::Previous(mut previous)) => {
debug_assert!(previous.as_ref().next.is_none());
previous.as_mut().next = Some(new);
}
None => {
first = Some(new);
}
}

// Update new variable
let new_identifier = identifier_iterator.next().unwrap();
let new_variable = VariableAlias {
identifier: new_identifier,
index: None,
};
let res = variable_map
.borrow_mut()
.insert(VariableAlias::from(variable.clone()), new_variable.clone());
assert!(res.is_none()); // Assert isn't pre-existing
*variable = Variable::from(new_variable);

// Update existing variables
for tail_variable in tail.iter_mut().filter_map(Value::variable_mut) {
let VariableAlias { identifier, index } = variable_map
.borrow()
.get(&VariableAlias::from(tail_variable.clone()))
.unwrap()
.clone();
*tail_variable = Variable {
addressing: tail_variable.addressing.clone(),
identifier,
index,
};
}

// Go next statement.
debug_assert!(current.as_ref().child.is_none());
if let Some(next) = current.as_ref().next {
stack.push((
next,
Some(Preceding::Previous(new)),
next_carry,
variable_map,
));
new.as_mut().next = None;
} else if let Some((next, old_variable_map)) = next_carry {
stack.push((next, Some(Preceding::Previous(new)), None, old_variable_map));
new.as_mut().next = None;
}
debug_assert_eq!(new.as_ref().next, None);
debug_assert_eq!(new.as_ref().child, None);
}
_ => todo!(),
},
Expand All @@ -1505,7 +1456,15 @@ pub unsafe fn inline_functions(node: NonNull<NewNode>) -> NonNull<NewNode> {

// Create new node.
let dst = alloc::alloc(alloc::Layout::new::<NewNode>()).cast::<NewNode>();
ptr::copy(current.as_ptr(), dst, 1);
ptr::write(
dst,
NewNode {
statement: current.as_ref().statement.clone(),
preceding,
child: None,
next: None,
},
);
let mut new = NonNull::new(dst).unwrap();

let [Value::Variable(lhs), Value::Variable(Variable {
Expand Down Expand Up @@ -1570,18 +1529,27 @@ pub unsafe fn inline_functions(node: NonNull<NewNode>) -> NonNull<NewNode> {
stack.push((next, Some(Preceding::Previous(new)), None, old_variable_map));
new.as_mut().next = None;
}
debug_assert_eq!(new.as_ref().next, None);
debug_assert_eq!(new.as_ref().child, None);
}
x @ _ => todo!("{x:?}"),
},
// Else
_ => {
// Create new node.
let dst = alloc::alloc(alloc::Layout::new::<NewNode>()).cast::<NewNode>();
ptr::copy(current.as_ptr(), dst, 1);
ptr::write(
dst,
NewNode {
statement: current.as_ref().statement.clone(),
preceding,
child: None,
next: None,
},
);
let mut new = NonNull::new(dst).unwrap();

// Update new preceding.
new.as_mut().preceding = preceding;
match preceding {
Some(Preceding::Parent(mut parent)) => {
debug_assert!(parent.as_ref().child.is_none());
Expand All @@ -1605,7 +1573,6 @@ pub unsafe fn inline_functions(node: NonNull<NewNode>) -> NonNull<NewNode> {
.filter_map(Value::variable_mut)
{
let var = VariableAlias::from(variable.clone());
eprintln!("var: {var:?}");

let VariableAlias { identifier, index } =
variable_map.borrow().get(&var).unwrap().clone();
Expand Down Expand Up @@ -1638,6 +1605,8 @@ pub unsafe fn inline_functions(node: NonNull<NewNode>) -> NonNull<NewNode> {
stack.push((next, Some(Preceding::Previous(new)), None, old_variable_map));
new.as_mut().next = None;
}
debug_assert_eq!(new.as_ref().next, None);
debug_assert_eq!(new.as_ref().child, None);
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions syscalls.lang
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,13 @@ def write
mov x0 fd
mov x1 ptr
mov x2 len
svc 0
def read
fd := in[0]
ptr := &out
len := sizeof *ptr
mov x8 63
mov x0 fd
mov x1 ptr
mov x2 len
svc 0
11 changes: 7 additions & 4 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn variable_if_false() {
build_and_run(
b"include https://raw.githubusercontent.com/JonathanWoollett-Light/language/master/syscalls.lang\nx := 1\nif x = 2\n exit 1\nexit 0",
b"",
1
0
);
}

Expand All @@ -86,7 +86,7 @@ fn variable_if_true() {
build_and_run(
b"include https://raw.githubusercontent.com/JonathanWoollett-Light/language/master/syscalls.lang\nx := 2\nif x = 2\n exit 1\nexit 0",
b"",
2
1
);
}

Expand Down Expand Up @@ -193,8 +193,11 @@ fn build_and_run(source: &[u8], expected_stdout: &[u8], expected_code: i32) {
.output()
.unwrap();

// use std::fs::read_to_string;
// println!("--- included ---\n{}\n-----------",read_to_string(directory.join("build").join("included.abc")).unwrap());
use std::fs::read_to_string;
println!(
"--- included ---\n{}\n-----------",
read_to_string(directory.join("build").join("included.abc")).unwrap()
);
// println!("--- inlined ---\n{}\n-----------",read_to_string(directory.join("build").join("inlined.abc")).unwrap());
// println!("--- optimized ---\n{}\n-----------",read_to_string(directory.join("build").join("optimized.abc")).unwrap());
// println!("--- assembly ---\n{}\n-----------",read_to_string(directory.join("build").join("assembly.s")).unwrap());
Expand Down

0 comments on commit bfd647a

Please sign in to comment.