ast: implement base value type
This commit is contained in:
parent
0c1d66186e
commit
a0e09b9613
3 changed files with 133 additions and 19 deletions
141
src/ast/val.rs
141
src/ast/val.rs
|
@ -1,25 +1,138 @@
|
|||
// See the end of this file for copyright and license terms.
|
||||
|
||||
pub enum Value {
|
||||
Bool(bool),
|
||||
Int(i64),
|
||||
String(String),
|
||||
use std::fmt;
|
||||
|
||||
/// Any primitive data type a [`Val`](Val) can hold.
|
||||
pub enum Type {
|
||||
Bool,
|
||||
Int,
|
||||
String,
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub fn type_name(&self) -> &'static str {
|
||||
match self {
|
||||
Value::Bool(_) => "boolean",
|
||||
Value::Int(_) => "int",
|
||||
Value::String(_) => "string",
|
||||
pub trait Val {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ValueError {
|
||||
msg: String,
|
||||
expected: Type,
|
||||
actual: Type,
|
||||
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 {
|
||||
Type::Bool => "bool",
|
||||
Type::Int => "int",
|
||||
Type::String => "string",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Type {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "\"{}\"", self.name())
|
||||
}
|
||||
}
|
||||
|
||||
// Copyright (C) 2021 Fefie <owo@fef.moe>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::str::Chars;
|
||||
|
||||
use cursor::Cursor;
|
||||
use self::cursor::Cursor;
|
||||
|
||||
mod cursor;
|
||||
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
// See the end of this file for copyright and license terms.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::Keys;
|
||||
use std::str::Chars;
|
||||
|
||||
pub mod lex;
|
||||
mod lex;
|
||||
use crate::lex::{Lexer, SyntaxError};
|
||||
|
||||
pub mod parser;
|
||||
|
||||
mod parser;
|
||||
use parser::Parser;
|
||||
use std::collections::hash_map::Keys;
|
||||
|
||||
mod ast;
|
||||
|
||||
pub struct Config {
|
||||
nodes: HashMap<String, Node>,
|
||||
|
|
Loading…
Reference in a new issue