Start working on calls
This commit is contained in:
@@ -201,11 +201,11 @@ enum Op {
|
|||||||
Guard { const_value: Rc<Form>, side: (Option<Rc<Form>>, Rc<Cont>) },
|
Guard { const_value: Rc<Form>, side: (Option<Rc<Form>>, Rc<Cont>) },
|
||||||
Debug,
|
Debug,
|
||||||
Define { sym: String },
|
Define { sym: String },
|
||||||
Prim { p: Prim },
|
|
||||||
Const { con: Rc<Form> },
|
Const { con: Rc<Form> },
|
||||||
Lookup { sym: String },
|
Lookup { sym: String },
|
||||||
|
Call(Vec<usize>),
|
||||||
|
Loop(Vec<usize>),
|
||||||
Return,
|
Return,
|
||||||
Loop,
|
|
||||||
}
|
}
|
||||||
impl fmt::Display for Op {
|
impl fmt::Display for Op {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
@@ -213,10 +213,10 @@ impl fmt::Display for Op {
|
|||||||
Op::Guard { const_value, side } => write!(f, "Guard({const_value})"),
|
Op::Guard { const_value, side } => write!(f, "Guard({const_value})"),
|
||||||
Op::Debug => write!(f, "Debug"),
|
Op::Debug => write!(f, "Debug"),
|
||||||
Op::Define { sym } => write!(f, "Define({sym})"),
|
Op::Define { sym } => write!(f, "Define({sym})"),
|
||||||
Op::Prim { p } => write!(f, "Prim{p:?}"),
|
|
||||||
Op::Const { con } => write!(f, "Const_{con}"),
|
Op::Const { con } => write!(f, "Const_{con}"),
|
||||||
Op::Lookup { sym } => write!(f, "Lookup({sym})"),
|
Op::Lookup { sym } => write!(f, "Lookup({sym})"),
|
||||||
Op::Loop => write!(f, "Loop"),
|
Op::Call(params) => write!(f, "Call({:?})", params),
|
||||||
|
Op::Loop(params) => write!(f, "Loop({:?})", params),
|
||||||
Op::Return => write!(f, "Return"),
|
Op::Return => write!(f, "Return"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,10 +226,11 @@ struct Trace {
|
|||||||
id: ID,
|
id: ID,
|
||||||
// needs to track which are constants
|
// needs to track which are constants
|
||||||
ops: Vec<Op>,
|
ops: Vec<Op>,
|
||||||
|
param_stack: Vec<usize>,
|
||||||
}
|
}
|
||||||
impl Trace {
|
impl Trace {
|
||||||
fn new(id: ID) -> Self {
|
fn new(id: ID) -> Self {
|
||||||
Trace { id, ops: vec![] }
|
Trace { id, ops: vec![], param_stack: vec![] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl fmt::Display for Trace {
|
impl fmt::Display for Trace {
|
||||||
@@ -239,6 +240,13 @@ impl fmt::Display for Trace {
|
|||||||
write!(f, " {}", op)?;
|
write!(f, " {}", op)?;
|
||||||
}
|
}
|
||||||
write!(f, " ]")?;
|
write!(f, " ]")?;
|
||||||
|
if !self.param_stack.is_empty() {
|
||||||
|
write!(f, "[")?;
|
||||||
|
for s in &self.param_stack {
|
||||||
|
write!(f, " {}", s)?;
|
||||||
|
}
|
||||||
|
write!(f, " ]")?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,6 +278,11 @@ impl Ctx {
|
|||||||
}
|
}
|
||||||
fn trace_running(&self) -> bool { self.tracing.is_some() }
|
fn trace_running(&self) -> bool { self.tracing.is_some() }
|
||||||
|
|
||||||
|
fn trace_call_bit(&mut self) {
|
||||||
|
if let Some(trace) = &mut self.tracing {
|
||||||
|
trace.param_stack.push(trace.ops.len()-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Though I guess that means call start should recieve the parameters
|
// Though I guess that means call start should recieve the parameters
|
||||||
// also, for like variables, it should guard on what function
|
// also, for like variables, it should guard on what function
|
||||||
// if dynamic, interacts with the constant tracking
|
// if dynamic, interacts with the constant tracking
|
||||||
@@ -294,16 +307,24 @@ impl Ctx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(trace) = &mut self.tracing {
|
if let Some(trace) = &mut self.tracing {
|
||||||
|
let f_params = trace.param_stack.split_off(trace.param_stack.len()-arg_len-1); // include function
|
||||||
if let Some(id) = id {
|
if let Some(id) = id {
|
||||||
if trace.id == id {
|
if trace.id == id {
|
||||||
trace.ops.push(Op::Loop);
|
// check for tail recursion
|
||||||
println!("Ending trace at recursive call!");
|
if trace.param_stack.is_empty() {
|
||||||
|
trace.ops.push(Op::Loop(f_params));
|
||||||
|
println!("Ending trace at tail recursive call!");
|
||||||
println!("\t{}", trace);
|
println!("\t{}", trace);
|
||||||
self.traces.insert(id, self.tracing.take().unwrap());
|
self.traces.insert(id, self.tracing.take().unwrap());
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
// call, and also we have to suspend tracing?
|
||||||
|
// can treat same as dynamic call if suspend, same thing really
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// either inline (prim/closure) or dynamic call
|
// either inline (prim/closure) or dynamic call
|
||||||
|
trace.ops.push(Op::Call(f_params));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn trace_call_end(&mut self, id: ID) {
|
fn trace_call_end(&mut self, id: ID) {
|
||||||
@@ -334,11 +355,6 @@ impl Ctx {
|
|||||||
trace.ops.push(Op::Define { sym: sym.to_owned() });
|
trace.ops.push(Op::Define { sym: sym.to_owned() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn trace_call_bit(&mut self) {
|
|
||||||
if let Some(trace) = &mut self.tracing {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn trace_lookup(&mut self, s: &str) {
|
fn trace_lookup(&mut self, s: &str) {
|
||||||
if let Some(trace) = &mut self.tracing {
|
if let Some(trace) = &mut self.tracing {
|
||||||
trace.ops.push(Op::Lookup { sym: s.to_owned() });
|
trace.ops.push(Op::Lookup { sym: s.to_owned() });
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ fn main() -> Result<()> {
|
|||||||
;(define faft2 (lambda (n a) (if (= n 1) a (faft2 (- n 1) (+ n a)))))
|
;(define faft2 (lambda (n a) (if (= n 1) a (faft2 (- n 1) (+ n a)))))
|
||||||
;(debug 'gonna_faft2_it)
|
;(debug 'gonna_faft2_it)
|
||||||
;(debug faft2)
|
;(debug faft2)
|
||||||
|
;(debug (faft2 6 1))
|
||||||
;(debug (faft2 400 1))
|
;(debug (faft2 400 1))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user