I'm currently working on creating the programming language described in "Writing an Interpreter in Go", but I'm trying to write the code in Rust.
I have the following struct representing the lexer:
struct Lexer<'a> {
input: &'a [u8], // assume the text input is all ascii
curr_pos: Cell<usize>,
read_pos: Cell<usize>,
curr_char: Cell<char>,
}
and the following struct representing a token:
struct Token<'a> {
tokenType: TokenType<'a>,
literal: &'a str,
}
where tokenType
is an enum representing the various kinds of tokens. It's pretty standard, but I'm having trouble with the ownership of literal
.
When I try to set create a token:
Token {tokenType: TokenType::ASSIGN, literal: &self.curr_char.get().to_string()}
I get an error about the value &self.curr_char.get().to_string()
not living long enough. How do ownership rules come into play here, and what is the best way to "give" a Token
its value?
Here's the full code:
use std::cell::Cell;
use std::str;
use std::char;
#[derive(Debug, PartialEq)]
enum TokenType<'a> {
ILLEGAL,
EOF,
IDENT(&'a str),
INT(i64),
ASSIGN,
PLUS,
COMMA,
SEMICOLON,
LPAREN,
RPAREN,
LBRACE,
RBRACE,
FUNCTION,
LET,
}
struct Token<'a> {
tokenType: TokenType<'a>,
literal: &'a str,
}
struct Lexer<'a> {
input: &'a [u8], // assume the text input is all ascii
curr_pos: Cell<usize>,
read_pos: Cell<usize>,
curr_char: Cell<char>,
}
impl<'a> Lexer<'a> {
fn next_token(&self) -> Token {
const NULL_CHAR: char = 0 as char;
let token = match self.curr_char.get() {
'=' => Token {tokenType: TokenType::ASSIGN, literal: &self.curr_char.get().to_string()},
';' => Token {tokenType: TokenType::SEMICOLON, literal: &self.curr_char.get().to_string()},
'(' => Token {tokenType: TokenType::LPAREN, literal: &self.curr_char.get().to_string()},
')' => Token {tokenType: TokenType::RPAREN, literal: &self.curr_char.get().to_string()},
'{' => Token {tokenType: TokenType::LBRACE, literal: &self.curr_char.get().to_string()},
'}' => Token {tokenType: TokenType::RBRACE, literal: &self.curr_char.get().to_string()},
',' => Token {tokenType: TokenType::COMMA, literal: &self.curr_char.get().to_string()},
'+' => Token {tokenType: TokenType::PLUS, literal: &self.curr_char.get().to_string()},
'\0' => Token {tokenType: TokenType::EOF, literal: &self.curr_char.get().to_string()},
}
}
}