~fd/cane-lang

8b2f87791b1dabfa12a7da1ac01adec9cba778f0 — Ersei Saggi 10 months ago 17dfd7d
Variables
4 files changed, 156 insertions(+), 19 deletions(-)

A demos/variables.cn
M src/interpreter.rs
M src/main.rs
M src/stdtypes.rs
A demos/variables.cn => demos/variables.cn +17 -0
@@ 0,0 1,17 @@
;
It's pretty simple to define a variable
You need: the data, and a string as a name.
~

((1 2 3 4 add) `myvarname' defvar)
(myvarname `\n' print)
(myvarname `\n' print)
(myvarname `\n' print)
(myvarname `\n' print)

; All variables are immutable! You can replace the variable, but you can't edit it. ~

((1 2 3 4 add) `myvarname' defvar)
(myvarname `\n' print)
((1 2 3 4 5 add) `myvarname' defvar)
(myvarname `\n' print)

M src/interpreter.rs => src/interpreter.rs +118 -6
@@ 29,7 29,6 @@ const WHITESPACE: [u8; 3] = [b' ', b'\n', b'\t'];

#[derive(Debug)]
struct Call {
    pos: Option<SeekFrom>,
    data: Data,
    state: Option<State>,
    token: String,


@@ 38,15 37,11 @@ struct Call {
impl Call {
    fn new(initial_state: State) -> Call {
        Call {
            pos: None,
            data: Data::new(Types::LIST),
            state: Some(initial_state),
            token: "".to_string(),
        }
    }
    fn get_pos(&mut self) -> &mut Option<SeekFrom> {
        &mut self.pos
    }
    fn get_data(&mut self) -> &mut Data {
        &mut self.data
    }


@@ 204,6 199,67 @@ where
                                    )
                                    .unwrap();
                                }
                                "defact" => {
                                    let key = self
                                        .call_stack
                                        .last_mut()
                                        .unwrap()
                                        .get_data()
                                        .get_list()
                                        .pop_back();
                                    if key.is_none() {
                                        return Err(Error::new(
                                            ErrorKind::InvalidData,
                                            "No action name found".to_string(),
                                        ));
                                    }
                                    let act = self
                                        .call_stack
                                        .last_mut()
                                        .unwrap()
                                        .get_data()
                                        .get_list()
                                        .pop_back();
                                    if act.is_none() {
                                        return Err(Error::new(
                                            ErrorKind::InvalidData,
                                            "No action found".to_string(),
                                        ));
                                    }
                                    let mut action = act.unwrap();
                                    action.as_action();
                                    self.variables.insert(key.unwrap().to_string(), action);
                                }
                                "defvar" => {
                                    let key = self
                                        .call_stack
                                        .last_mut()
                                        .unwrap()
                                        .get_data()
                                        .get_list()
                                        .pop_back();
                                    if key.is_none() {
                                        return Err(Error::new(
                                            ErrorKind::InvalidData,
                                            "No action name found".to_string(),
                                        ));
                                    }
                                    let var = self
                                        .call_stack
                                        .last_mut()
                                        .unwrap()
                                        .get_data()
                                        .get_list()
                                        .pop_back();
                                    if var.is_none() {
                                        return Err(Error::new(
                                            ErrorKind::InvalidData,
                                            "No variable found".to_string(),
                                        ));
                                    }
                                    self.variables
                                        .insert(key.unwrap().to_string(), var.unwrap());
                                }
                                _ => {
                                    match Rational::from_str_radix(
                                        self.call_stack.last_mut().unwrap().get_token().as_str(),


@@ 223,6 279,28 @@ where
                                            reset = false;
                                        }
                                    }
                                    match self
                                        .variables
                                        .get(self.call_stack.last_mut().unwrap().get_token())
                                    {
                                        Some(data) => {
                                            match data.get_kind() {
                                                Types::ACTION => {
                                                    unimplemented!()
                                                }
                                                _ => {
                                                    self.call_stack
                                                        .last_mut()
                                                        .unwrap()
                                                        .get_data()
                                                        .get_list()
                                                        .push(data.clone());
                                                reset = true;
                                                }
                                            }
                                        }
                                        None => (),
                                    }
                                }
                            }



@@ 294,7 372,9 @@ where
                                .unwrap()
                                .get_data()
                                .get_string()
                                .push_str(std::str::from_utf8(&[Symbols::StringEnd as u8]).unwrap()),
                                .push_str(
                                    std::str::from_utf8(&[Symbols::StringEnd as u8]).unwrap(),
                                ),
                            b'\\' => self
                                .call_stack
                                .last_mut()


@@ 433,4 513,36 @@ mod tests {

        assert_eq!(stdout, b"11");
    }

    #[test]
    fn test_variable() {
        let mut c = Cursor::new(Vec::new());
        let mut stdout = Vec::new();

        let test_input = b"((1 1 2 add) `var' defvar) (var print)" as &[u8];
        c.write_all(test_input).unwrap();
        let mut reader = BufReader::new(c);
        reader.rewind().unwrap();

        let mut runner = Interpreter::new(reader, &mut stdout);
        runner.execute().unwrap();

        assert_eq!(stdout, b"4");
    }

    #[test]
    fn test_variable_overwrite() {
        let mut c = Cursor::new(Vec::new());
        let mut stdout = Vec::new();

        let test_input = b"((1 1 2 add) `var' defvar) (var print) (1 `var' defvar) (var print)" as &[u8];
        c.write_all(test_input).unwrap();
        let mut reader = BufReader::new(c);
        reader.rewind().unwrap();

        let mut runner = Interpreter::new(reader, &mut stdout);
        runner.execute().unwrap();

        assert_eq!(stdout, b"41");
    }
}

M src/main.rs => src/main.rs +14 -5
@@ 13,9 13,18 @@ fn main() -> std::io::Result<()> {
        ));
    }

    let f = File::open(args.get(1).unwrap())?;
    let reader = BufReader::new(f);
    let mut stdout = std::io::stdout();
    let mut runner = Interpreter::new(reader, &mut stdout);
    runner.execute()
    let mut iter = args.iter();
    iter.next();

    for name in iter {
        let f = File::open(name)?;
        let reader = BufReader::new(f);
        let mut stdout = std::io::stdout();
        let mut runner = Interpreter::new(reader, &mut stdout);
        match runner.execute() {
            Ok(..) => (),
            Err(e) => return Err(e),
        }
    }
    Ok(())
}

M src/stdtypes.rs => src/stdtypes.rs +7 -8
@@ 1,7 1,6 @@
use rug::Rational;
use std::collections::LinkedList;
use std::fmt;
use std::io::SeekFrom;

/// Represents a doubly-linked list
#[derive(Clone, Debug)]


@@ 27,7 26,6 @@ pub struct Data {
    val_string: String,
    val_number: Number,
    val_list: List,
    val_action_location: SeekFrom,
}

/// Converts a number to a list. Creates a list with just the number inside of it.


@@ 116,11 114,7 @@ impl fmt::Display for Data {
            Types::STRING => write!(f, "{}", self.val_string),
            Types::NUMBER => write!(f, "{}", self.val_number),
            Types::LIST => write!(f, "{}", self.val_list),
            Types::ACTION => match self.val_action_location {
                SeekFrom::Start(a) => write!(f, "function at {}", a),
                SeekFrom::End(a) => write!(f, "function end {}", a),
                SeekFrom::Current(a) => write!(f, "function offset {}", a),
            },
            Types::ACTION => write!(f, "{}", self.val_string),
        }
    }
}


@@ 210,7 204,6 @@ impl Data {
            val_string: "".to_string(),
            val_number: Number(Rational::new()),
            val_list: List(LinkedList::new()),
            val_action_location: SeekFrom::Start(0),
        }
    }
    /// Sets the node to type list and updates the data in the internal list


@@ 283,6 276,12 @@ impl Data {
        self.kind = Types::STRING;
        return self;
    }
    /// Converts internal data and type into a string.
    pub fn as_action(&mut self) -> &mut Data {
        self.get_string();
        self.kind = Types::ACTION;
        return self;
    }
    /// Converts internal data and type into a number.
    pub fn as_number(&mut self) -> &mut Data {
        self.get_number();