Skip to content

Commit

Permalink
fire: Add handling for Blocks and Returns
Browse files Browse the repository at this point in the history
  • Loading branch information
CohenArthur committed May 14, 2023
1 parent db90b9f commit 0a6cecc
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 5 deletions.
2 changes: 1 addition & 1 deletion fir/src/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl<T: Debug> Fir<T> {
} => {
check!(to => Kind::Function { .. }, node);
check!(@generics => Kind::TypeReference { .. }, node);
check!(@args => Kind::TypedValue { .. } | Kind::Constant(_), node);
check!(@args => Kind::TypedValue { .. } | Kind::Constant(_) | Kind::Call { .. }, node);
}
Kind::Type {
generics,
Expand Down
74 changes: 70 additions & 4 deletions fire/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,32 @@ pub struct Instance {
pub(crate) data: Vec<u8>,
}

impl From<i64> for Instance {
fn from(value: i64) -> Instance {
Instance {
ty: "int",
// origin: node.origin,
data: value.to_le_bytes().to_vec(),
}
}
}

impl From<&str> for Instance {
fn from(value: &str) -> Instance {
Instance {
ty: "string",
// orgin: node.origin,
data: value.as_bytes().to_owned(),
}
}
}

impl From<&String> for Instance {
fn from(value: &String) -> Instance {
Instance::from(value.as_str())
}
}

// FIXME: How do we deal with the fact that we're acting on a Flat representation?
// FIXME: Is the [`Fir`] stable? Can we just access the last node as the entry point to the [`Fir`]?
// then it makes everything super easy actually
Expand Down Expand Up @@ -114,7 +140,7 @@ impl Fire {
fn fire_block(
&mut self,
fir: &Fir<FlattenData<'_>>,
_node: &Node<FlattenData<'_>>,
node: &Node<FlattenData<'_>>,
stmts: &[RefIdx],
) {
// How do we deal with returns in this system?
Expand All @@ -123,6 +149,12 @@ impl Fire {
self.fire_node(fir, node);
});

if let Some(last_stmt) = stmts.last() {
if let Kind::Return(_) = &fir.nodes[&last_stmt.unwrap()].kind {
self.transfer(last_stmt, node.origin)
}
}

// FIXME: This is invalid, isn't it?
// FIXME: or should we just return () here?
// FIXME: If the last value is a return, we need to have this node's ID refer to the value as well
Expand Down Expand Up @@ -225,6 +257,19 @@ impl Fire {
self.allocate(node.origin, instance);
}

fn fire_return(
&mut self,
fir: &Fir<FlattenData<'_>>,
node: &Node<FlattenData<'_>>,
expr: &Option<RefIdx>,
) {
if let Some(returned) = expr {
self.fire_node_ref(fir, returned);

self.transfer(returned, node.origin);
} // FIXME: Allocate None otherwise?
}

fn fire_node_ref(&mut self, fir: &Fir<FlattenData<'_>>, node_ref: &RefIdx) {
let node = &fir.nodes[&node_ref.unwrap()];

Expand All @@ -236,8 +281,6 @@ impl Fire {
// -> we perform the call, allocate data, and then look it up when accessing `x`? Is `x` a reference to call()? a move? that ties in the move semantics right?
// where we would "move" the value from the call's OriginId to x's OriginId
fn fire_node(&mut self, fir: &Fir<FlattenData<'_>>, node: &Node<FlattenData<'_>>) {
dbg!(&node.data.ast);

match &node.kind {
Kind::Constant(c) => self.fire_constant(fir, node, c),
Kind::Statements(stmts) => self.fire_block(fir, node, stmts),
Expand All @@ -248,6 +291,7 @@ impl Fire {
} => self.fire_call(fir, node, to, args),
Kind::Binding { to } => self.fire_binding(fir, node, to),
Kind::TypedValue { value, ty } => self.fire_typed_value(fir, node, value, ty),
Kind::Return(expr) => self.fire_return(fir, node, expr),
// Kind::TypeReference(r) => self.traverse_type_reference(fir, node, r),
// Kind::Generic { default } => self.traverse_generic(fir, node, default),
// Kind::Type { generics, fields } => self.traverse_type(fir, node, generics, fields),
Expand All @@ -272,7 +316,6 @@ impl Fire {
// false_block,
// } => self.traverse_condition(fir, node, condition, true_block, false_block),
// Kind::Loop { condition, block } => self.traverse_loop(fir, node, condition, block),
// Kind::Return(expr) => self.traverse_return(fir, node, expr),
_ => {},
}
}
Expand Down Expand Up @@ -322,6 +365,16 @@ mod tests {
};
}

#[test]
fn last_value() {
let ast = ast! {
"jinko"
};

let result = fir!(ast).interpret();
assert_eq!(result, Some(Instance::from("jinko")))
}

#[test]
fn call() {
let ast = ast! {
Expand All @@ -331,5 +384,18 @@ mod tests {
};

let result = fir!(ast).interpret();
assert_eq!(result, Some(Instance::from(15)))
}

#[test]
fn nested_call() {
let ast = ast! {
func id(x: string) -> string { x }

id(id(id(id("jinko"))))
};

let result = fir!(ast).interpret();
assert_eq!(result, Some(Instance::from("jinko")))
}
}

0 comments on commit 0a6cecc

Please sign in to comment.