Website typing improvements, uncommitted JIT work
This commit is contained in:
@@ -200,14 +200,24 @@ impl Env {
|
|||||||
enum Op {
|
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> },
|
||||||
|
Lookup { sym: String },
|
||||||
|
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 {
|
||||||
match self {
|
match self {
|
||||||
Op::Guard { const_value, side } => write!(f, "Guard"),
|
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::Lookup { sym } => write!(f, "Lookup({sym})"),
|
||||||
|
Op::Loop => write!(f, "Loop"),
|
||||||
|
Op::Return => write!(f, "Return"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,29 +269,49 @@ impl Ctx {
|
|||||||
ID { id: self.id_counter }
|
ID { id: self.id_counter }
|
||||||
}
|
}
|
||||||
fn trace_running(&self) -> bool { self.tracing.is_some() }
|
fn trace_running(&self) -> bool { self.tracing.is_some() }
|
||||||
fn trace_call_start(&mut self, id: ID) {
|
|
||||||
|
// Though I guess that means call start should recieve the parameters
|
||||||
|
// also, for like variables, it should guard on what function
|
||||||
|
// if dynamic, interacts with the constant tracking
|
||||||
|
// 5 options
|
||||||
|
// - not tracing, closure - do stats
|
||||||
|
// - not tracing, prim - do nothing
|
||||||
|
// - tracing, Constant Prim - inline prim
|
||||||
|
// - tracing, Constant Closure - inline call
|
||||||
|
// - tracing, Dynamic - emit call
|
||||||
|
fn trace_call_start(&mut self, arg_len: usize, id: Option<ID>) {
|
||||||
|
|
||||||
// Needs to take and use parameters for mid-trace
|
// Needs to take and use parameters for mid-trace
|
||||||
// needs to guard on function called if non-constant
|
// needs to guard on function called if non-constant
|
||||||
|
|
||||||
let entry = self.func_calls.entry(id).or_insert(0);
|
if let Some(id) = id {
|
||||||
println!("tracing call start for {id}, has been called {} times so far", *entry);
|
let entry = self.func_calls.entry(id).or_insert(0);
|
||||||
*entry += 1;
|
println!("tracing call start for {id}, has been called {} times so far", *entry);
|
||||||
if let Some(trace) = &self.tracing {
|
*entry += 1;
|
||||||
if trace.id == id {
|
if *entry > 1 && self.tracing.is_none() && self.traces.get(&id).is_none() {
|
||||||
println!("Ending trace at recursive call!");
|
self.tracing = Some(Trace::new(id));
|
||||||
println!("\t{}", trace);
|
return; // don't record self, of course
|
||||||
self.traces.insert(id, self.tracing.take().unwrap());
|
|
||||||
}
|
}
|
||||||
} else if *entry > 1 && self.traces.get(&id).is_none() {
|
}
|
||||||
self.tracing = Some(Trace::new(id));
|
if let Some(trace) = &mut self.tracing {
|
||||||
|
if let Some(id) = id {
|
||||||
|
if trace.id == id {
|
||||||
|
trace.ops.push(Op::Loop);
|
||||||
|
println!("Ending trace at recursive call!");
|
||||||
|
println!("\t{}", trace);
|
||||||
|
self.traces.insert(id, self.tracing.take().unwrap());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// either inline (prim/closure) or dynamic call
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn trace_call_end(&mut self, id: ID) {
|
fn trace_call_end(&mut self, id: ID) {
|
||||||
// associate with it or something
|
// associate with it or something
|
||||||
println!("tracing call end for {id}");
|
println!("tracing call end for {id}");
|
||||||
if let Some(trace) = &self.tracing {
|
if let Some(trace) = &mut self.tracing {
|
||||||
if trace.id == id {
|
if trace.id == id {
|
||||||
|
trace.ops.push(Op::Return);
|
||||||
println!("Ending trace at end of call!");
|
println!("Ending trace at end of call!");
|
||||||
println!("\t{}", trace);
|
println!("\t{}", trace);
|
||||||
self.traces.insert(id, self.tracing.take().unwrap());
|
self.traces.insert(id, self.tracing.take().unwrap());
|
||||||
@@ -309,23 +339,15 @@ impl Ctx {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Trace call start, of course, handles the other side!
|
|
||||||
// Though I guess that means call start should recieve the parameters
|
|
||||||
// also, for like variables, it should guard on what function
|
|
||||||
// if dynamic, interacts with the constant tracking
|
|
||||||
fn trace_prim(&mut self, p: &Prim) {
|
|
||||||
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 {
|
||||||
// TODO
|
trace.ops.push(Op::Lookup { sym: s.to_owned() });
|
||||||
|
// constant depends on which env
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn trace_constant(&mut self, c: &Rc<Form>) {
|
fn trace_constant(&mut self, c: &Rc<Form>) {
|
||||||
if let Some(trace) = &mut self.tracing {
|
if let Some(trace) = &mut self.tracing {
|
||||||
// TODO
|
trace.ops.push(Op::Const { con: Rc::clone(c) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn trace_lambda(&mut self, params: &[String], e: &Rc<RefCell<Env>>, body: &Rc<Form>) {
|
fn trace_lambda(&mut self, params: &[String], e: &Rc<RefCell<Env>>, body: &Rc<Form>) {
|
||||||
@@ -438,13 +460,13 @@ pub fn eval(f: Rc<Form>) -> Result<Rc<Form>> {
|
|||||||
for (name, value) in ps.iter().zip(evaled_iter) {
|
for (name, value) in ps.iter().zip(evaled_iter) {
|
||||||
new_env.borrow_mut().define(name.to_string(), value);
|
new_env.borrow_mut().define(name.to_string(), value);
|
||||||
}
|
}
|
||||||
ctx.trace_call_start(*id);
|
ctx.trace_call_start(arg_len, Some(*id));
|
||||||
c = Cont::Eval { c: Rc::new(Cont::Ret { e: Rc::clone(&e), id: *id, c: nc }) };
|
c = Cont::Eval { c: Rc::new(Cont::Ret { e: Rc::clone(&e), id: *id, c: nc }) };
|
||||||
f = Rc::clone(&b);
|
f = Rc::clone(&b);
|
||||||
e = new_env;
|
e = new_env;
|
||||||
},
|
},
|
||||||
Form::Prim(p) => {
|
Form::Prim(p) => {
|
||||||
ctx.trace_prim(p);
|
ctx.trace_call_start(arg_len, None);
|
||||||
let a = evaled_iter.next().unwrap();
|
let a = evaled_iter.next().unwrap();
|
||||||
f = match comb.prim().unwrap() {
|
f = match comb.prim().unwrap() {
|
||||||
Prim::Car => a.car()?,
|
Prim::Car => a.car()?,
|
||||||
|
|||||||
@@ -69,8 +69,20 @@ var wordflick = function () {
|
|||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while (words[i][offset] == ' ') {
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
offset = Math.max(offset-4, 0);
|
for (var j = 0; j < 4; j++) {
|
||||||
|
if (offset > 0) {
|
||||||
|
offset--;
|
||||||
|
if (words[i][offset] == '>') {
|
||||||
|
while (words[i][offset] != '<') {
|
||||||
|
offset--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
document.getElementsByClassName('word')[0].innerHTML = part;
|
document.getElementsByClassName('word')[0].innerHTML = part;
|
||||||
|
|||||||
Reference in New Issue
Block a user