truegrf 2.1.0

TrueGRF YAML to GRF compiler
Documentation
use super::super::engine::Engine;
use super::super::stack::{
    Stack,
    StackVariable,
};

pub fn handle_token(engine: &mut Engine) -> Result<(), String> {
    if engine.stack.len() < 2 {
        return Err(format!("Expected two parameters for lookup, found {}", engine.stack.len()));
    }

    let rhs = engine.stack.pop().unwrap();
    let lhs = engine.stack.pop().unwrap();

    let result = match (&lhs, rhs) {
        (Stack::Variable(StackVariable::List(list_name)), Stack::Number(value)) => {
            let list = engine.constants.get_mut(list_name).unwrap();

            list.entry(value).or_insert(0);

            Stack::Identifier(format!("{}:{}", list_name, value))
        },
        (Stack::Variable(StackVariable::List(_)), _) => {
            return Err("Left hand side of lookup must be a number".to_string());
        },
        (Stack::Variable(StackVariable::CargoDict(dict_name)), Stack::Ctt(value)) => {
            let value = if let Some(value) = engine.ctt.get(&value) {
                value
            } else {
                return Err("Unknown cargo type".to_string());
            };

            if let Some(dict) = engine.constants.get_mut(dict_name) {
                dict.entry(*value as i32).or_insert(0);
            } else {
                return Err(format!("Unknown variable '{}'.", dict_name));
            }

            Stack::Identifier(format!("{}:{}", dict_name, value))
        },
        (Stack::Variable(StackVariable::CargoDict(_)), _) => {
            return Err("Right hand side of lookup must be a CTT".to_string());
        },
        _ => {
            return Err("Left hand side of lookup must be a list".to_string());
        },
    };

    engine.stack.push(result);

    Ok(())
}