[Question]: Modifying self

Hello!
In a piece of code, I needed to modify a value in self (a struct). However, for some reason it will not change.

#[derive(Clone, Debug)]
pub struct SymbolTable {
    pub symbols: HashMap<String, Symbol>,
    pub parent : Box<Option<SymbolTable>>
}
impl SymbolTable {
    pub fn get(&mut self, name: String) -> Option<Symbol> {
        println!("{:#?}", self.symbols); // Shows an empty HashMap
        match self.symbols.get(name.as_str()) {
            Some(value) => return Some(value.clone()),
            None        => return None
        }
    }

    pub fn set(&mut self, name: String, value: types::Type) {
        self.symbols.insert(
            name,
            Symbol {value}
        );
        println!("{:#?}", self.symbols); // Shows a hashmap with a symbol in it.
    }
}

I am running:

symbols.set("x".to_string(), myvalue);
symbols.get("x".to_string());

It does compile, it does set, but only locally so the get method says it didn't find the symbol.
Please let me know how to get it to set globally.

Please make a playground demo with exactly what you're running and seeing.

For what it's worth, your code here all looks correct, so I would be checking for problems elsewhere. (Are you accidentally running a different version of your code? Is all the code exactly as you've pasted it here? Could the incorrect output come from somewhere else in your program?)

I've taken some liberty to fill in the gaps in your code, and for me it displays everything perfectly.

Take another look at your code, maybe?

Are you dropping the value of your SymbolsTable before it's able to save anything?

I have no idea where a problem could be and I also have no idea what to give you other than the repository from when I asked this question: toto-bird/Peri.dot at 091f770cd58e38d5c82f3538f1be7a27550a8f8a.

The SymbolTable is in the src/version/context.rs file. It is created at the end of the src/version/interpreter.rs file.

Where are you running these?

What's the context before them?

How do you define the symbols variable?

What do you mean by that?

Are you only able to get the right symbol in the scope of the called set function?

Do you want to create a global, persistent SymbolsTable that any part of your program, from anywhere, could access? Or do you have something else in mind?

symbols.set: file interpreter.rs in Interpreter.visit_varinitnode line 113.
symbols.get: file interpreter.rs in Interpreter.visit_varaccessnode line 86.

Turns out I was slightly wrong about the locally and globally. It is 'set' and the symbols.get does actually set it. However, it never gets to the 'get' method.

I think I figured it out. I need to pass in a &Context to each of my visit methods, not a Context. However, I'm tired, I have school tomorrow, so I'm going to sleep on it. Thank you for your help.

It's got to be a &mut Context, though. You're always welcome.

1 Like

Guess what worked! Changing all of the Contexts to &mut Context.

# Peri.dot

var x = 1 2+ 3* # Yes peri.dot uses rpn math, leave me alone.
x # Used to return an identifier exception, now returns 9.
# Console Output

LEXER RESULT => <KEYWORD: var> <KEYWORD: x> <EQUALS> <INT: 1> <INT: 2> <PLUS> <INT: 3> <TIMES> <EOL> <KEYWORD: x> <EOL> <EOF> 
PARSER RESULT => (x = ((i1 <PLUS> i2) <TIMES> i3))
PARSER RESULT => x
{
    "x": Symbol {
        value: Type {
            value: IntType(
                9,
            ),
            start: LexerPosition {
                index: 8,
                line: 0,
                column: 8,
                file: "test.peri",
                script: "var x = 1 2+ 3*\nx",
                lines: [
                    "var x = 1 2+ 3*",
                    "x",
                ],
            },
            end: LexerPosition {
                index: 16,
                line: 1,
                column: 0,
                file: "test.peri",
                script: "var x = 1 2+ 3*\nx",
                lines: [
                    "var x = 1 2+ 3*",
                    "x",
                ],
            },
            context: Context {
                display: "<root>",
                parent: None,
                parententry: None,
                symbols: SymbolTable {
                    symbols: {},
                    parent: None,
                },
            },
        },
    },
}
INTERPRETER RESULT => 9
INTERPRETER RESULT => 9 
// It worked!         ^

Thank you so much for your help.