#`?` doesn't propagate the error

16 messages · Page 1 of 1 (latest)

winged nimbus
#
pub fn execute_block(&mut self, stmts: &Vec<Stmt>, environment: Rc<RefCell<Environment>>) -> Result<(), Option<Literal>> {
        let previous = self.environment.clone();
        self.environment = environment;

        for statement in stmts {
            println!("{:?}", self.execute(statement)?);
        }

        self.environment = previous;
        Ok(())
}```
Result: ```()
()
()
()
()
...```
#

? doesn't propagate the error

#

Code without ?: ```rust
pub fn execute_block(&mut self, stmts: &Vec<Stmt>, environment: Rc<RefCell<Environment>>) -> Result<(), Option<Literal>> {
let previous = self.environment.clone();
self.environment = environment;

    for statement in stmts {
        println!("{:?}", self.execute(statement));
    }

    self.environment = previous;
    Ok(())
}```

Result:

Ok(())
Err(Some(Float(1.0)))
Ok(())
Err(Some(Float(-1.0)))
Ok(())
Err(Some(Float(-3.0)))
...```
earnest wraith
#

Are you sure you're not just calling this function repeatedly?

#

Try adding a dbg around the relevant call: dbg!(self.execute(statement))?. It should print the return value just before ? deals with it

winged nimbus
#
    Some(
        Float(
            -3613.0,
        ),
    ),
)
[src/interpreter.rs:138] self.execute(statement) = Ok(
    (),
)```
#

These are the only two places where I am calling it rust Stmt::Block(statements) => { self.execute_block(statements, Environment::from_existing(Rc::clone(&self.environment)))?; Ok(()) }

#
fn call(&self, interpreter: &mut Interpreter, arguments: &[Option<Literal>]) -> Option<Literal> {
        let environment = &interpreter.globals;
        if let Stmt::Function(name, params, body) = &self.declaration {
            for i in 0..params.len() {
                environment.borrow_mut().define(params.get(i)?.lexeme.clone(), arguments.get(i).unwrap().clone());
            }
            if let Err(value) = interpreter.execute_block(body, environment.clone()) {
                return value;
            }
        }
        None
    }```
#

If I return a fake value, it works fine fn execute(&mut self, stmt: &Stmt) -> Result<(), Option<Literal>> { self.accept_statement(stmt); Err(Some(Literal::Float(3.0))) }

#
fatal runtime error: stack overflow``` I get this error if I don't
earnest wraith
#

Idk, that ? is somehow failing to do its one job in a trivial case seems extremely unlikely. I'd add some printlns around the code (say, at the start of execute_block) to make sure you're not calling it again

winged nimbus
#

I tried to return it manually by using if let but ended up with the same error. So maybe it's not ?

winged nimbus
#

The Java call stack currently looks roughly like this:

Interpreter.visitReturnStmt()
Interpreter.visitIfStmt()
Interpreter.executeBlock()
Interpreter.visitBlockStmt()
Interpreter.visitWhileStmt()
Interpreter.executeBlock()
LoxFunction.call()
Interpreter.visitCallExpr()

We need to get from the top of the stack all the way back to call(). I don’t know about you, but to me that sounds like exceptions. When we execute a return statement, we’ll use an exception to unwind the interpreter past the visit methods of all of the containing statements back to the code that began executing the body.

real vapor
#

putting your function's result in Err is very confusing