Add built-in option definition
This commit is contained in:
parent
d3601be44c
commit
4c68bc0260
@ -13,16 +13,27 @@ pub struct EnumDefinition {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||
enum VariantContent {
|
||||
pub enum VariantContent {
|
||||
Type(Type),
|
||||
TypeDefinition(TypeDefinition),
|
||||
None,
|
||||
}
|
||||
|
||||
impl EnumDefinition {
|
||||
pub fn new(identifier: Identifier, variants: Vec<(Identifier, VariantContent)>) -> Self {
|
||||
Self {
|
||||
identifier,
|
||||
variants,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn instantiate(&self, variant: String, content: Value) -> EnumInstance {
|
||||
EnumInstance::new(self.identifier.inner().clone(), variant, content)
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
}
|
||||
|
||||
impl AbstractTree for EnumDefinition {
|
||||
|
@ -3,7 +3,7 @@ use tree_sitter::Node as SyntaxNode;
|
||||
|
||||
use crate::{
|
||||
error::{RuntimeError, SyntaxError, ValidationError},
|
||||
AbstractTree, Context, EnumDefinition, Format, StructDefinition, Type, Value,
|
||||
AbstractTree, Context, EnumDefinition, Format, Identifier, StructDefinition, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||
@ -12,6 +12,15 @@ pub enum TypeDefinition {
|
||||
Struct(StructDefinition),
|
||||
}
|
||||
|
||||
impl TypeDefinition {
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
match self {
|
||||
TypeDefinition::Enum(enum_definition) => enum_definition.identifier(),
|
||||
TypeDefinition::Struct(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AbstractTree for TypeDefinition {
|
||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||
SyntaxError::expect_syntax_node(source, "type_definition", node)?;
|
||||
|
38
src/built_in_type_definitions.rs
Normal file
38
src/built_in_type_definitions.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use enum_iterator::{all, Sequence};
|
||||
|
||||
use crate::{EnumDefinition, Identifier, Type, TypeDefinition, VariantContent};
|
||||
|
||||
static OPTION: OnceLock<TypeDefinition> = OnceLock::new();
|
||||
|
||||
pub fn all_built_in_type_definitions() -> impl Iterator<Item = BuiltInTypeDefinition> {
|
||||
all()
|
||||
}
|
||||
|
||||
#[derive(Sequence)]
|
||||
pub enum BuiltInTypeDefinition {
|
||||
Option,
|
||||
}
|
||||
|
||||
impl BuiltInTypeDefinition {
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
BuiltInTypeDefinition::Option => "Option",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> &TypeDefinition {
|
||||
match self {
|
||||
BuiltInTypeDefinition::Option => OPTION.get_or_init(|| {
|
||||
TypeDefinition::Enum(EnumDefinition::new(
|
||||
Identifier::new("Option"),
|
||||
vec![
|
||||
(Identifier::new("Some"), VariantContent::Type(Type::Any)),
|
||||
(Identifier::new("None"), VariantContent::None),
|
||||
],
|
||||
))
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,10 @@ use std::{
|
||||
sync::{Arc, RwLock, RwLockReadGuard},
|
||||
};
|
||||
|
||||
use crate::{error::rw_lock_error::RwLockError, Type, TypeDefinition, Value};
|
||||
use crate::{
|
||||
built_in_type_definitions::all_built_in_type_definitions, error::rw_lock_error::RwLockError,
|
||||
Type, TypeDefinition, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Context {
|
||||
@ -79,6 +82,12 @@ impl Context {
|
||||
}
|
||||
}
|
||||
|
||||
for built_in_definition in all_built_in_type_definitions() {
|
||||
if key == built_in_definition.name() {
|
||||
return Ok(Some(built_in_definition.get().clone()));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ pub use tree_sitter::Node as SyntaxNode;
|
||||
|
||||
pub mod abstract_tree;
|
||||
pub mod built_in_functions;
|
||||
pub mod built_in_type_definitions;
|
||||
pub mod context;
|
||||
pub mod error;
|
||||
pub mod interpret;
|
||||
|
27
tests/built_in_type_definitions.rs
Normal file
27
tests/built_in_type_definitions.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use dust_lang::*;
|
||||
|
||||
#[test]
|
||||
fn option() {
|
||||
assert_eq!(
|
||||
interpret("new Option:None"),
|
||||
Ok(Value::Enum(EnumInstance::new(
|
||||
"Option".to_string(),
|
||||
"None".to_string(),
|
||||
Value::none()
|
||||
)))
|
||||
);
|
||||
assert_eq!(
|
||||
interpret(
|
||||
"
|
||||
opt <Option<int>> = new Option:Some(1);
|
||||
|
||||
opt
|
||||
"
|
||||
),
|
||||
Ok(Value::Enum(EnumInstance::new(
|
||||
"Option".to_string(),
|
||||
"Some".to_string(),
|
||||
Value::Integer(1),
|
||||
)))
|
||||
);
|
||||
}
|
@ -350,6 +350,10 @@ module.exports = grammar({
|
||||
'num',
|
||||
'str',
|
||||
$.identifier,
|
||||
seq(
|
||||
$.identifier,
|
||||
$.type_specification,
|
||||
),
|
||||
seq('[', $.type, ']'),
|
||||
seq(
|
||||
'(',
|
||||
@ -496,7 +500,6 @@ module.exports = grammar({
|
||||
struct_instance: $ =>
|
||||
seq('new', $.identifier, $.map),
|
||||
|
||||
|
||||
built_in_value: $ =>
|
||||
choice(
|
||||
'args',
|
||||
|
@ -1068,6 +1068,19 @@
|
||||
"type": "SYMBOL",
|
||||
"name": "identifier"
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "identifier"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "type_specification"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
|
@ -716,6 +716,10 @@
|
||||
{
|
||||
"type": "type",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "type_specification",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user