diff --git a/ablescript/src/ast.rs b/ablescript/src/ast.rs index 5b49b8a6..edf276c5 100644 --- a/ablescript/src/ast.rs +++ b/ablescript/src/ast.rs @@ -8,7 +8,7 @@ //! just plain subroutines and they do not return any value, //! so their calls are statements. -use crate::variables::Value; +use crate::{base_55::char2num, variables::Value}; use std::{fmt::Debug, hash::Hash}; type Span = std::ops::Range; @@ -165,6 +165,7 @@ pub enum Expr { #[derive(Debug, PartialEq, Clone, Hash)] pub enum Literal { + Char(char), Int(isize), Str(String), } @@ -172,6 +173,7 @@ pub enum Literal { impl From for Value { fn from(lit: Literal) -> Self { match lit { + Literal::Char(c) => Self::Int(char2num(c)), Literal::Int(i) => Self::Int(i), Literal::Str(s) => Self::Str(s), } diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index 684abe65..8134a3e2 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -10,7 +10,6 @@ use crate::{ ast::{Assignable, AssignableKind, Expr, Spanned, Stmt}, - base_55, consts::ablescript_consts, error::{Error, ErrorKind}, variables::{Functio, Value, ValueRef, Variable}, @@ -516,14 +515,7 @@ impl ExecEnv { /// Get the value of a variable. Throw an error if the variable is /// inaccessible or banned. fn get_var(&self, name: &Spanned) -> Result { - // One-letter names are reserved as base55 numbers. - let mut chars = name.item.chars(); - if let (Some(first), None) = (chars.next(), chars.next()) { - return Ok(Value::Int(base_55::char2num(first))); - } - - // Otherwise, search for the name in the stack from top to - // bottom. + // Search for the name in the stack from top to bottom. match self .stack .iter() diff --git a/ablescript/src/lexer.rs b/ablescript/src/lexer.rs index 7754ebbc..3da3842d 100644 --- a/ablescript/src/lexer.rs +++ b/ablescript/src/lexer.rs @@ -116,8 +116,12 @@ pub enum Token { #[regex(r"-?[0-9]+", get_value)] Integer(isize), + // A character (to be base-55 converted) + #[regex(r"\p{XID_Start}", get_value)] + Char(char), + /// An identifier - #[regex(r"\p{XID_Start}[\p{XID_Continue}]*", get_ident)] + #[regex(r"\p{XID_Start}[\p{XID_Continue}]+", get_ident)] Identifier(String), #[regex(r"owo .*")] diff --git a/ablescript/src/parser.rs b/ablescript/src/parser.rs index 6f2c5f99..977fd73a 100644 --- a/ablescript/src/parser.rs +++ b/ablescript/src/parser.rs @@ -101,6 +101,7 @@ impl<'source> Parser<'source> { Token::Identifier(_) | Token::String(_) | Token::Integer(_) + | Token::Char(_) | Token::Aint | Token::LeftBracket | Token::LeftParen => Ok(Spanned::new( @@ -183,6 +184,10 @@ impl<'source> Parser<'source> { })), start..self.lexer.span().end, )), + Token::Char(c) => Ok(Spanned::new( + Expr::Literal(Literal::Char(c)), + start..self.lexer.span().end, + )), Token::LeftBracket => match buf.take() { Some(buf) => Ok(Spanned::new( @@ -416,12 +421,10 @@ impl<'source> Parser<'source> { /// Consists of condition and block, there is no else fn if_flow(&mut self) -> Result { self.require(Token::LeftParen)?; - - let cond = self.expr_flow(Token::RightParen)?; - - let body = self.get_block()?; - - Ok(Stmt::If { cond, body }) + Ok(Stmt::If { + cond: self.expr_flow(Token::RightParen)?, + body: self.get_block()?, + }) } /// Parse functio flow @@ -429,7 +432,6 @@ impl<'source> Parser<'source> { /// functio $ident (a, b, c) { ... } fn functio_flow(&mut self) -> Result { let ident = self.get_ident()?; - self.require(Token::LeftParen)?; let mut params = vec![]; @@ -606,7 +608,7 @@ mod tests { #[test] fn simple_math() { - let code = "1 * (a + 3) / 666 print;"; + let code = "1 * (num + 3) / 666 print;"; let expected = &[Spanned { item: Stmt::Print(Spanned { item: Expr::BinOp { @@ -619,7 +621,7 @@ mod tests { rhs: Box::new(Spanned { item: Expr::BinOp { lhs: Box::new(Spanned { - item: Expr::Variable("a".to_owned()), + item: Expr::Variable("num".to_owned()), span: 5..6, }), rhs: Box::new(Spanned { @@ -651,11 +653,11 @@ mod tests { #[test] fn variable_declaration() { - let code = "dim a 42;"; + let code = "dim var 42;"; let expected = &[Spanned { item: Stmt::Dim { ident: Spanned { - item: "a".to_owned(), + item: "var".to_owned(), span: 4..5, }, init: Some(Spanned { @@ -672,13 +674,13 @@ mod tests { #[test] fn if_flow() { - let code = "if (a = always) { /*Buy Able products!*/ print; }"; + let code = "if (var = always) { /*Buy Able products!*/ print; }"; let expected = &[Spanned { item: Stmt::If { cond: Spanned { item: Expr::BinOp { lhs: Box::new(Spanned { - item: Expr::Variable("a".to_owned()), + item: Expr::Variable("var".to_owned()), span: 4..5, }), rhs: Box::new(Spanned {