ast: implement base value type

This commit is contained in:
anna 2021-04-19 19:17:22 +02:00
parent 0c1d66186e
commit a0e09b9613
Signed by: fef
GPG key ID: EC22E476DC2D3D84
3 changed files with 133 additions and 19 deletions

View file

@ -1,25 +1,138 @@
// See the end of this file for copyright and license terms. // See the end of this file for copyright and license terms.
pub enum Value { use std::fmt;
Bool(bool),
Int(i64), /// Any primitive data type a [`Val`](Val) can hold.
String(String), pub enum Type {
Bool,
Int,
String,
} }
impl Value { pub trait Val {
pub fn type_name(&self) -> &'static str { fn clone(&self) -> Box<dyn Val>;
fn typ(&self) -> Type;
fn bool(&self) -> Result<&bool, TypeError> {
Err(TypeError::new(self.typ(), Type::Bool))
}
fn int(&self) -> Result<&i64, TypeError> {
Err(TypeError::new(self.typ(), Type::Int))
}
fn string(&self) -> Result<&str, TypeError> {
Err(TypeError::new(self.typ(), Type::String))
}
}
/// The actual data structure behind [`Val`](Val)
struct Data<T: Clone> {
data: T,
}
/// Construct a new bool value
pub fn bool(val: bool) -> Box<dyn Val> {
Box::new(Data::new(val))
}
/// Construct a new int value
pub fn int(val: i64) -> Box<dyn Val> {
Box::new(Data::new(val))
}
/// Construct a new string value
pub fn string(val: &str) -> Box<dyn Val> {
Box::new(Data::new(String::from(val)))
}
impl<T: Clone> Data<T> {
pub fn new(data: T) -> Data<T> {
Data {
data
}
}
}
impl Val for Data<bool> {
fn clone(&self) -> Box<dyn Val> {
Box::new(Data {
data: self.data
})
}
fn typ(&self) -> Type {
Type::Bool
}
fn bool(&self) -> Result<&bool, TypeError> {
Ok(&self.data)
}
}
impl Val for Data<i64> {
fn clone(&self) -> Box<dyn Val> {
Box::new(Data {
data: self.data
})
}
fn typ(&self) -> Type {
Type::Int
}
fn int(&self) -> Result<&i64, TypeError> {
Ok(&self.data)
}
}
impl Val for Data<String> {
fn clone(&self) -> Box<dyn Val> {
Box::new(Data {
data: self.data.clone()
})
}
fn typ(&self) -> Type {
Type::String
}
fn string(&self) -> Result<&str, TypeError> {
Ok(&self.data)
}
}
pub struct TypeError {
pub msg: String,
pub actual: Type,
pub expected: Type,
}
impl TypeError {
pub fn new(actual: Type, expected: Type) -> TypeError {
TypeError {
msg: format!("Cannot convert from {} to {}", actual, expected),
actual,
expected,
}
}
}
impl Type {
pub fn name(&self) -> &'static str {
match self { match self {
Value::Bool(_) => "boolean", Type::Bool => "bool",
Value::Int(_) => "int", Type::Int => "int",
Value::String(_) => "string", Type::String => "string",
} }
} }
} }
pub struct ValueError { impl fmt::Display for Type {
msg: String, fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
expected: Type, write!(f, "\"{}\"", self.name())
actual: Type, }
} }
// Copyright (C) 2021 Fefie <owo@fef.moe> // Copyright (C) 2021 Fefie <owo@fef.moe>

View file

@ -2,7 +2,7 @@
use std::str::Chars; use std::str::Chars;
use cursor::Cursor; use self::cursor::Cursor;
mod cursor; mod cursor;

View file

@ -1,15 +1,16 @@
// See the end of this file for copyright and license terms. // See the end of this file for copyright and license terms.
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::hash_map::Keys;
use std::str::Chars; use std::str::Chars;
pub mod lex; mod lex;
use crate::lex::{Lexer, SyntaxError}; use crate::lex::{Lexer, SyntaxError};
pub mod parser; mod parser;
use parser::Parser; use parser::Parser;
use std::collections::hash_map::Keys;
mod ast;
pub struct Config { pub struct Config {
nodes: HashMap<String, Node>, nodes: HashMap<String, Node>,