From 1b826430f0e2771eccbf458bf6312776f54c84fb Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Wed, 22 May 2024 17:45:29 -0400 Subject: [PATCH] Change all script strings to Rc --- build.rs | 5 +++-- src/eval/environment.rs | 1 + src/lex.rs | 26 ++++++++++++++------------ src/parse.rs | 16 ++++------------ 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/build.rs b/build.rs index 2f9e4e4..46ee1e4 100644 --- a/build.rs +++ b/build.rs @@ -22,7 +22,8 @@ fn do_ast_codegen(mut output: W) { ) .unwrap(); - define_imports(&mut output, &["crate::lex::Token"]).expect("failed to define imports"); + define_imports(&mut output, &["crate::lex::Token", "std::rc::Rc"]) + .expect("failed to define imports"); writeln!(output).unwrap(); define_literals( @@ -30,7 +31,7 @@ fn do_ast_codegen(mut output: W) { "LiteralValue", &BTreeMap::from([ ("Number", Some("f64")), - ("String", Some("String")), + ("String", Some("Rc")), ("True", None), ("False", None), ("Nil", None), diff --git a/src/eval/environment.rs b/src/eval/environment.rs index e2f3f9e..d61d125 100644 --- a/src/eval/environment.rs +++ b/src/eval/environment.rs @@ -25,6 +25,7 @@ impl Environment { const ROOT_KEY: u32 = 0; #[must_use] + #[allow(dead_code)] pub fn new() -> Self { Self::default() } diff --git a/src/lex.rs b/src/lex.rs index 6f3de44..0e7fa19 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -1,5 +1,8 @@ use itertools::{FoldWhile, Itertools}; -use std::iter::{self, Peekable}; +use std::{ + iter::{self, Peekable}, + rc::Rc, +}; use thiserror::Error; use crate::ScriptError; @@ -28,8 +31,8 @@ pub enum TokenKind { LessEqual, // Literals - Identifier(String), - String(String), + Identifier(Rc), + String(Rc), Number(f64), // Keywords @@ -92,10 +95,6 @@ impl Token { &self.kind } - pub fn into_kind(self) -> TokenKind { - self.kind - } - pub fn lexeme(&self) -> &str { &self.lexeme } @@ -326,16 +325,19 @@ fn lex_remaining_string_literal>( .into_inner(); if end_found { + let lexeme = format!("\"{contents}\""); + // must include quotes + let length = contents.len() + 2; + Ok(Consumed { token: Some(Token { - kind: TokenKind::String(contents.clone()), - lexeme: format!("\"{contents}\""), + kind: TokenKind::String(contents.into()), + lexeme, line: start_line + newlines, }), span: Span { lines: newlines, - // must include the quotes - chars: contents.len() + 2, + chars: length, }, }) } else { @@ -401,6 +403,6 @@ fn tokenize_word(word: String) -> TokenKind { "true" => TokenKind::True, "var" => TokenKind::Var, "while" => TokenKind::While, - _other => TokenKind::Identifier(word), + _other => TokenKind::Identifier(word.into()), } } diff --git a/src/parse.rs b/src/parse.rs index b1eb400..7b60011 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -81,7 +81,6 @@ fn parse, F: FnMut(ScriptError)>( line: error.line.unwrap_or_default(), location: String::new(), }); - todo!("{}", error.message); } } } @@ -329,17 +328,10 @@ fn parse_primary>(iter: &mut Peekable) -> Result { - // TODO: we used to do this with into_kind, but we need to change Token to Rc to fix cloning issues - // special case to avoid cloning - match token.kind() { - TokenKind::String(string) => Ok(Expr::Literal { - value: LiteralValue::String(string.clone()), - token, - }), - _ => unreachable!(), - } - } + TokenKind::String(value) => Ok(Expr::Literal { + value: LiteralValue::String(value.clone()), + token, + }), TokenKind::LeftParen => { let expr = parse_expression(iter)?; match_token_kind!(iter, TokenKind::RightParen)