about summary refs log tree commit diff
path: root/src/interpreter
diff options
context:
space:
mode:
authorGriffin Smith <root@gws.fyi>2021-03-14T15·53-0400
committerGriffin Smith <root@gws.fyi>2021-03-14T15·53-0400
commit39656a3801bb311edd9ebb65e92a24fc48f69ec7 (patch)
treed408937901c7789c033373019a94e014a03522a8 /src/interpreter
parent32a5c0ff0fc58aa6721c1e0ad41950bde2d66744 (diff)
Add string support to the frontend
Diffstat (limited to 'src/interpreter')
-rw-r--r--src/interpreter/mod.rs1
-rw-r--r--src/interpreter/value.rs23
2 files changed, 24 insertions, 0 deletions
diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs
index 85a8928cbf9a..d414dedf8560 100644
--- a/src/interpreter/mod.rs
+++ b/src/interpreter/mod.rs
@@ -29,6 +29,7 @@ impl<'a> Interpreter<'a> {
             Expr::Ident(id, _) => self.resolve(id),
             Expr::Literal(Literal::Int(i), _) => Ok((*i).into()),
             Expr::Literal(Literal::Bool(b), _) => Ok((*b).into()),
+            Expr::Literal(Literal::String(s), _) => Ok(s.clone().into()),
             Expr::UnaryOp { op, rhs, .. } => {
                 let rhs = self.eval(rhs)?;
                 match op {
diff --git a/src/interpreter/value.rs b/src/interpreter/value.rs
index 5e55825160cd..a1a579aec8db 100644
--- a/src/interpreter/value.rs
+++ b/src/interpreter/value.rs
@@ -1,7 +1,9 @@
+use std::borrow::Cow;
 use std::convert::TryFrom;
 use std::fmt::{self, Display};
 use std::ops::{Add, Div, Mul, Neg, Sub};
 use std::rc::Rc;
+use std::result;
 
 use derive_more::{Deref, From, TryInto};
 
@@ -22,15 +24,28 @@ pub enum Val<'a> {
     Int(i64),
     Float(f64),
     Bool(bool),
+    String(Cow<'a, str>),
     Function(Function<'a>),
 }
 
+impl<'a> TryFrom<Val<'a>> for String {
+    type Error = ();
+
+    fn try_from(value: Val<'a>) -> result::Result<Self, Self::Error> {
+        match value {
+            Val::String(s) => Ok(s.into_owned()),
+            _ => Err(()),
+        }
+    }
+}
+
 impl<'a> fmt::Debug for Val<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             Val::Int(x) => f.debug_tuple("Int").field(x).finish(),
             Val::Float(x) => f.debug_tuple("Float").field(x).finish(),
             Val::Bool(x) => f.debug_tuple("Bool").field(x).finish(),
+            Val::String(s) => f.debug_tuple("String").field(s).finish(),
             Val::Function(Function { type_, .. }) => {
                 f.debug_struct("Function").field("type_", type_).finish()
             }
@@ -62,6 +77,7 @@ impl<'a> Display for Val<'a> {
             Val::Int(x) => x.fmt(f),
             Val::Float(x) => x.fmt(f),
             Val::Bool(x) => x.fmt(f),
+            Val::String(s) => write!(f, "{:?}", s),
             Val::Function(Function { type_, .. }) => write!(f, "<{}>", type_),
         }
     }
@@ -73,6 +89,7 @@ impl<'a> Val<'a> {
             Val::Int(_) => Type::Int,
             Val::Float(_) => Type::Float,
             Val::Bool(_) => Type::Bool,
+            Val::String(_) => Type::CString,
             Val::Function(Function { type_, .. }) => Type::Function(type_.clone()),
         }
     }
@@ -178,3 +195,9 @@ impl TypeOf for f64 {
         Type::Float
     }
 }
+
+impl TypeOf for String {
+    fn type_of() -> Type {
+        Type::CString
+    }
+}