Chars are no longer special case of identifiers

This commit is contained in:
Erin 2022-04-18 21:04:19 +02:00 committed by ondra05
parent 0eb2698242
commit 6dd32793bb
4 changed files with 24 additions and 24 deletions

View file

@ -8,7 +8,7 @@
//! just plain subroutines and they do not return any value, //! just plain subroutines and they do not return any value,
//! so their calls are statements. //! so their calls are statements.
use crate::variables::Value; use crate::{base_55::char2num, variables::Value};
use std::{fmt::Debug, hash::Hash}; use std::{fmt::Debug, hash::Hash};
type Span = std::ops::Range<usize>; type Span = std::ops::Range<usize>;
@ -165,6 +165,7 @@ pub enum Expr {
#[derive(Debug, PartialEq, Clone, Hash)] #[derive(Debug, PartialEq, Clone, Hash)]
pub enum Literal { pub enum Literal {
Char(char),
Int(isize), Int(isize),
Str(String), Str(String),
} }
@ -172,6 +173,7 @@ pub enum Literal {
impl From<Literal> for Value { impl From<Literal> for Value {
fn from(lit: Literal) -> Self { fn from(lit: Literal) -> Self {
match lit { match lit {
Literal::Char(c) => Self::Int(char2num(c)),
Literal::Int(i) => Self::Int(i), Literal::Int(i) => Self::Int(i),
Literal::Str(s) => Self::Str(s), Literal::Str(s) => Self::Str(s),
} }

View file

@ -10,7 +10,6 @@
use crate::{ use crate::{
ast::{Assignable, AssignableKind, Expr, Spanned, Stmt}, ast::{Assignable, AssignableKind, Expr, Spanned, Stmt},
base_55,
consts::ablescript_consts, consts::ablescript_consts,
error::{Error, ErrorKind}, error::{Error, ErrorKind},
variables::{Functio, Value, ValueRef, Variable}, variables::{Functio, Value, ValueRef, Variable},
@ -516,14 +515,7 @@ impl ExecEnv {
/// Get the value of a variable. Throw an error if the variable is /// Get the value of a variable. Throw an error if the variable is
/// inaccessible or banned. /// inaccessible or banned.
fn get_var(&self, name: &Spanned<String>) -> Result<Value, Error> { fn get_var(&self, name: &Spanned<String>) -> Result<Value, Error> {
// One-letter names are reserved as base55 numbers. // Search for the name in the stack from top to bottom.
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.
match self match self
.stack .stack
.iter() .iter()

View file

@ -116,8 +116,12 @@ pub enum Token {
#[regex(r"-?[0-9]+", get_value)] #[regex(r"-?[0-9]+", get_value)]
Integer(isize), Integer(isize),
// A character (to be base-55 converted)
#[regex(r"\p{XID_Start}", get_value)]
Char(char),
/// An identifier /// An identifier
#[regex(r"\p{XID_Start}[\p{XID_Continue}]*", get_ident)] #[regex(r"\p{XID_Start}[\p{XID_Continue}]+", get_ident)]
Identifier(String), Identifier(String),
#[regex(r"owo .*")] #[regex(r"owo .*")]

View file

@ -101,6 +101,7 @@ impl<'source> Parser<'source> {
Token::Identifier(_) Token::Identifier(_)
| Token::String(_) | Token::String(_)
| Token::Integer(_) | Token::Integer(_)
| Token::Char(_)
| Token::Aint | Token::Aint
| Token::LeftBracket | Token::LeftBracket
| Token::LeftParen => Ok(Spanned::new( | Token::LeftParen => Ok(Spanned::new(
@ -183,6 +184,10 @@ impl<'source> Parser<'source> {
})), })),
start..self.lexer.span().end, 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() { Token::LeftBracket => match buf.take() {
Some(buf) => Ok(Spanned::new( Some(buf) => Ok(Spanned::new(
@ -416,12 +421,10 @@ impl<'source> Parser<'source> {
/// Consists of condition and block, there is no else /// Consists of condition and block, there is no else
fn if_flow(&mut self) -> Result<Stmt, Error> { fn if_flow(&mut self) -> Result<Stmt, Error> {
self.require(Token::LeftParen)?; self.require(Token::LeftParen)?;
Ok(Stmt::If {
let cond = self.expr_flow(Token::RightParen)?; cond: self.expr_flow(Token::RightParen)?,
body: self.get_block()?,
let body = self.get_block()?; })
Ok(Stmt::If { cond, body })
} }
/// Parse functio flow /// Parse functio flow
@ -429,7 +432,6 @@ impl<'source> Parser<'source> {
/// functio $ident (a, b, c) { ... } /// functio $ident (a, b, c) { ... }
fn functio_flow(&mut self) -> Result<Stmt, Error> { fn functio_flow(&mut self) -> Result<Stmt, Error> {
let ident = self.get_ident()?; let ident = self.get_ident()?;
self.require(Token::LeftParen)?; self.require(Token::LeftParen)?;
let mut params = vec![]; let mut params = vec![];
@ -606,7 +608,7 @@ mod tests {
#[test] #[test]
fn simple_math() { fn simple_math() {
let code = "1 * (a + 3) / 666 print;"; let code = "1 * (num + 3) / 666 print;";
let expected = &[Spanned { let expected = &[Spanned {
item: Stmt::Print(Spanned { item: Stmt::Print(Spanned {
item: Expr::BinOp { item: Expr::BinOp {
@ -619,7 +621,7 @@ mod tests {
rhs: Box::new(Spanned { rhs: Box::new(Spanned {
item: Expr::BinOp { item: Expr::BinOp {
lhs: Box::new(Spanned { lhs: Box::new(Spanned {
item: Expr::Variable("a".to_owned()), item: Expr::Variable("num".to_owned()),
span: 5..6, span: 5..6,
}), }),
rhs: Box::new(Spanned { rhs: Box::new(Spanned {
@ -651,11 +653,11 @@ mod tests {
#[test] #[test]
fn variable_declaration() { fn variable_declaration() {
let code = "dim a 42;"; let code = "dim var 42;";
let expected = &[Spanned { let expected = &[Spanned {
item: Stmt::Dim { item: Stmt::Dim {
ident: Spanned { ident: Spanned {
item: "a".to_owned(), item: "var".to_owned(),
span: 4..5, span: 4..5,
}, },
init: Some(Spanned { init: Some(Spanned {
@ -672,13 +674,13 @@ mod tests {
#[test] #[test]
fn if_flow() { fn if_flow() {
let code = "if (a = always) { /*Buy Able products!*/ print; }"; let code = "if (var = always) { /*Buy Able products!*/ print; }";
let expected = &[Spanned { let expected = &[Spanned {
item: Stmt::If { item: Stmt::If {
cond: Spanned { cond: Spanned {
item: Expr::BinOp { item: Expr::BinOp {
lhs: Box::new(Spanned { lhs: Box::new(Spanned {
item: Expr::Variable("a".to_owned()), item: Expr::Variable("var".to_owned()),
span: 4..5, span: 4..5,
}), }),
rhs: Box::new(Spanned { rhs: Box::new(Spanned {