ast: implement base value type
This commit is contained in:
parent
0c1d66186e
commit
a0e09b9613
3 changed files with 133 additions and 19 deletions
139
src/ast/val.rs
139
src/ast/val.rs
|
@ -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>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::str::Chars;
|
use std::str::Chars;
|
||||||
|
|
||||||
use cursor::Cursor;
|
use self::cursor::Cursor;
|
||||||
|
|
||||||
mod cursor;
|
mod cursor;
|
||||||
|
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
Loading…
Reference in a new issue