Use single-letter identifiers as base-55 digits
This commit is contained in:
parent
7b21eaf48a
commit
585bf2e19f
|
@ -11,6 +11,7 @@ use std::collections::HashMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
base_55,
|
||||||
error::{Error, ErrorKind},
|
error::{Error, ErrorKind},
|
||||||
parser::item::{Expr, Iden, Item, Stmt},
|
parser::item::{Expr, Iden, Item, Stmt},
|
||||||
variables::{Value, Variable},
|
variables::{Value, Variable},
|
||||||
|
@ -140,7 +141,7 @@ impl ExecEnv {
|
||||||
}
|
}
|
||||||
Not(expr) => Bool(!bool::from(self.eval_expr(expr)?)),
|
Not(expr) => Bool(!bool::from(self.eval_expr(expr)?)),
|
||||||
Literal(value) => value.clone(),
|
Literal(value) => value.clone(),
|
||||||
Identifier(Iden(name)) => self.get_var(name)?.value.clone(),
|
Identifier(Iden(name)) => self.get_var(name)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,9 +205,17 @@ impl ExecEnv {
|
||||||
Ok(HaltStatus::Value(Value::Nul))
|
Ok(HaltStatus::Value(Value::Nul))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a shared reference to the value of a variable. Throw an
|
/// Get the value of a variable. Throw an error if the variable is
|
||||||
/// error if the variable is inaccessible or banned.
|
/// inaccessible or banned.
|
||||||
fn get_var(&self, name: &str) -> Result<&Variable, Error> {
|
fn get_var(&self, name: &str) -> Result<Value, Error> {
|
||||||
|
// One-letter names are reserved as base55 numbers.
|
||||||
|
let mut chars = name.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()
|
||||||
|
@ -215,7 +224,7 @@ impl ExecEnv {
|
||||||
{
|
{
|
||||||
Some(var) => {
|
Some(var) => {
|
||||||
if !var.melo {
|
if !var.melo {
|
||||||
Ok(var)
|
Ok(var.value.clone())
|
||||||
} else {
|
} else {
|
||||||
Err(Error {
|
Err(Error {
|
||||||
kind: ErrorKind::MeloVariable(name.to_owned()),
|
kind: ErrorKind::MeloVariable(name.to_owned()),
|
||||||
|
@ -235,8 +244,8 @@ impl ExecEnv {
|
||||||
/// Get a mutable reference to a variable. Throw an error if the
|
/// Get a mutable reference to a variable. Throw an error if the
|
||||||
/// variable is inaccessible or banned.
|
/// variable is inaccessible or banned.
|
||||||
fn get_var_mut(&mut self, name: &str) -> Result<&mut Variable, Error> {
|
fn get_var_mut(&mut self, name: &str) -> Result<&mut Variable, Error> {
|
||||||
// This function is almost exactly 22 lines of duplicated code
|
// This function has a lot of duplicated code with `get_var`,
|
||||||
// from get_var, which I feel like is a bad sign...
|
// which I feel like is a bad sign...
|
||||||
match self
|
match self
|
||||||
.stack
|
.stack
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
|
Loading…
Reference in a new issue