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)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
enum VariantContent {
|
pub enum VariantContent {
|
||||||
Type(Type),
|
Type(Type),
|
||||||
TypeDefinition(TypeDefinition),
|
TypeDefinition(TypeDefinition),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EnumDefinition {
|
impl EnumDefinition {
|
||||||
|
pub fn new(identifier: Identifier, variants: Vec<(Identifier, VariantContent)>) -> Self {
|
||||||
|
Self {
|
||||||
|
identifier,
|
||||||
|
variants,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn instantiate(&self, variant: String, content: Value) -> EnumInstance {
|
pub fn instantiate(&self, variant: String, content: Value) -> EnumInstance {
|
||||||
EnumInstance::new(self.identifier.inner().clone(), variant, content)
|
EnumInstance::new(self.identifier.inner().clone(), variant, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn identifier(&self) -> &Identifier {
|
||||||
|
&self.identifier
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for EnumDefinition {
|
impl AbstractTree for EnumDefinition {
|
||||||
|
@ -3,7 +3,7 @@ use tree_sitter::Node as SyntaxNode;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -12,6 +12,15 @@ pub enum TypeDefinition {
|
|||||||
Struct(StructDefinition),
|
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 {
|
impl AbstractTree for TypeDefinition {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "type_definition", node)?;
|
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},
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Context {
|
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)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ pub use tree_sitter::Node as SyntaxNode;
|
|||||||
|
|
||||||
pub mod abstract_tree;
|
pub mod abstract_tree;
|
||||||
pub mod built_in_functions;
|
pub mod built_in_functions;
|
||||||
|
pub mod built_in_type_definitions;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod interpret;
|
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',
|
'num',
|
||||||
'str',
|
'str',
|
||||||
$.identifier,
|
$.identifier,
|
||||||
|
seq(
|
||||||
|
$.identifier,
|
||||||
|
$.type_specification,
|
||||||
|
),
|
||||||
seq('[', $.type, ']'),
|
seq('[', $.type, ']'),
|
||||||
seq(
|
seq(
|
||||||
'(',
|
'(',
|
||||||
@ -496,7 +500,6 @@ module.exports = grammar({
|
|||||||
struct_instance: $ =>
|
struct_instance: $ =>
|
||||||
seq('new', $.identifier, $.map),
|
seq('new', $.identifier, $.map),
|
||||||
|
|
||||||
|
|
||||||
built_in_value: $ =>
|
built_in_value: $ =>
|
||||||
choice(
|
choice(
|
||||||
'args',
|
'args',
|
||||||
|
@ -1068,6 +1068,19 @@
|
|||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "identifier"
|
"name": "identifier"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "identifier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "type_specification"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
"members": [
|
"members": [
|
||||||
|
@ -716,6 +716,10 @@
|
|||||||
{
|
{
|
||||||
"type": "type",
|
"type": "type",
|
||||||
"named": true
|
"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