Implement struct definition and type
This commit is contained in:
parent
c7b189a83f
commit
16d443d8a6
@ -10,6 +10,7 @@ pub mod r#loop;
|
|||||||
pub mod map_index;
|
pub mod map_index;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
pub mod statement;
|
pub mod statement;
|
||||||
|
pub mod structure_definition;
|
||||||
pub mod r#type;
|
pub mod r#type;
|
||||||
pub mod value_node;
|
pub mod value_node;
|
||||||
pub mod r#while;
|
pub mod r#while;
|
||||||
@ -31,6 +32,7 @@ pub use self::{
|
|||||||
r#type::Type,
|
r#type::Type,
|
||||||
r#while::While,
|
r#while::While,
|
||||||
statement::Statement,
|
statement::Statement,
|
||||||
|
structure_definition::StructureDefinition,
|
||||||
value_node::ValueNode,
|
value_node::ValueNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,7 +3,10 @@ use crate::{
|
|||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{AbstractTree, Action, Assignment, Block, Expression, IfElse, Loop, Type, While};
|
use super::{
|
||||||
|
AbstractTree, Action, Assignment, Block, Expression, IfElse, Loop, StructureDefinition, Type,
|
||||||
|
While,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
@ -13,6 +16,7 @@ pub enum Statement {
|
|||||||
Expression(Expression),
|
Expression(Expression),
|
||||||
IfElse(IfElse),
|
IfElse(IfElse),
|
||||||
Loop(Loop),
|
Loop(Loop),
|
||||||
|
StructureDefinition(StructureDefinition),
|
||||||
While(While),
|
While(While),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,6 +30,9 @@ impl AbstractTree for Statement {
|
|||||||
Statement::IfElse(if_else) => if_else.expected_type(_context),
|
Statement::IfElse(if_else) => if_else.expected_type(_context),
|
||||||
Statement::Loop(r#loop) => r#loop.expected_type(_context),
|
Statement::Loop(r#loop) => r#loop.expected_type(_context),
|
||||||
Statement::While(r#while) => r#while.expected_type(_context),
|
Statement::While(r#while) => r#while.expected_type(_context),
|
||||||
|
Statement::StructureDefinition(structure_definition) => {
|
||||||
|
structure_definition.expected_type(_context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,6 +45,9 @@ impl AbstractTree for Statement {
|
|||||||
Statement::IfElse(if_else) => if_else.validate(_context),
|
Statement::IfElse(if_else) => if_else.validate(_context),
|
||||||
Statement::Loop(r#loop) => r#loop.validate(_context),
|
Statement::Loop(r#loop) => r#loop.validate(_context),
|
||||||
Statement::While(r#while) => r#while.validate(_context),
|
Statement::While(r#while) => r#while.validate(_context),
|
||||||
|
Statement::StructureDefinition(structure_definition) => {
|
||||||
|
structure_definition.validate(_context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +60,9 @@ impl AbstractTree for Statement {
|
|||||||
Statement::IfElse(if_else) => if_else.run(_context),
|
Statement::IfElse(if_else) => if_else.run(_context),
|
||||||
Statement::Loop(r#loop) => r#loop.run(_context),
|
Statement::Loop(r#loop) => r#loop.run(_context),
|
||||||
Statement::While(r#while) => r#while.run(_context),
|
Statement::While(r#while) => r#while.run(_context),
|
||||||
|
Statement::StructureDefinition(structure_definition) => {
|
||||||
|
structure_definition.run(_context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
39
src/abstract_tree/structure_definition.rs
Normal file
39
src/abstract_tree/structure_definition.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
use crate::{
|
||||||
|
context::Context,
|
||||||
|
error::{RuntimeError, ValidationError},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{AbstractTree, Action, Identifier, Type, WithPosition};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
|
pub struct StructureDefinition {
|
||||||
|
name: Identifier,
|
||||||
|
fields: Vec<(Identifier, WithPosition<Type>)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StructureDefinition {
|
||||||
|
pub fn new(name: Identifier, fields: Vec<(Identifier, WithPosition<Type>)>) -> Self {
|
||||||
|
Self { name, fields }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AbstractTree for StructureDefinition {
|
||||||
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
|
Ok(Type::None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(self, context: &Context) -> Result<Action, RuntimeError> {
|
||||||
|
let struct_type = Type::Structure {
|
||||||
|
name: self.name.clone(),
|
||||||
|
fields: self.fields,
|
||||||
|
};
|
||||||
|
|
||||||
|
context.set_type(self.name, struct_type)?;
|
||||||
|
|
||||||
|
Ok(Action::None)
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
error::{RuntimeError, TypeConflict, ValidationError},
|
error::{RuntimeError, TypeConflict, ValidationError},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{AbstractTree, Action};
|
use super::{AbstractTree, Action, WithPosition};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
@ -27,7 +27,7 @@ pub enum Type {
|
|||||||
String,
|
String,
|
||||||
Structure {
|
Structure {
|
||||||
name: Identifier,
|
name: Identifier,
|
||||||
fields: Vec<(Identifier, Type)>,
|
fields: Vec<(Identifier, WithPosition<Type>)>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,10 @@ pub enum ValueNode {
|
|||||||
),
|
),
|
||||||
Range(Range<i64>),
|
Range(Range<i64>),
|
||||||
String(String),
|
String(String),
|
||||||
|
Structure {
|
||||||
|
name: Identifier,
|
||||||
|
fields: Vec<(Identifier, Type)>,
|
||||||
|
},
|
||||||
Function {
|
Function {
|
||||||
parameters: Vec<(Identifier, WithPosition<Type>)>,
|
parameters: Vec<(Identifier, WithPosition<Type>)>,
|
||||||
return_type: WithPosition<Type>,
|
return_type: WithPosition<Type>,
|
||||||
@ -59,6 +63,7 @@ impl AbstractTree for ValueNode {
|
|||||||
.collect(),
|
.collect(),
|
||||||
return_type: Box::new(return_type.node.clone()),
|
return_type: Box::new(return_type.node.clone()),
|
||||||
},
|
},
|
||||||
|
ValueNode::Structure { name, fields } => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(r#type)
|
Ok(r#type)
|
||||||
@ -160,6 +165,7 @@ impl AbstractTree for ValueNode {
|
|||||||
return_type,
|
return_type,
|
||||||
body,
|
body,
|
||||||
} => Value::function(parameters, return_type, body),
|
} => Value::function(parameters, return_type, body),
|
||||||
|
ValueNode::Structure { name, fields } => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Action::Return(value))
|
Ok(Action::Return(value))
|
||||||
@ -228,6 +234,25 @@ impl Ord for ValueNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Function { .. }, _) => Ordering::Greater,
|
(Function { .. }, _) => Ordering::Greater,
|
||||||
|
(
|
||||||
|
Structure {
|
||||||
|
name: left_name,
|
||||||
|
fields: left_fields,
|
||||||
|
},
|
||||||
|
Structure {
|
||||||
|
name: right_name,
|
||||||
|
fields: right_fields,
|
||||||
|
},
|
||||||
|
) => todo!(),
|
||||||
|
(
|
||||||
|
Structure { name, fields },
|
||||||
|
Function {
|
||||||
|
parameters,
|
||||||
|
return_type,
|
||||||
|
body,
|
||||||
|
},
|
||||||
|
) => todo!(),
|
||||||
|
(Structure { name, fields }, _) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,6 +224,7 @@ pub fn lexer<'src>() -> impl Parser<
|
|||||||
just("map").padded(),
|
just("map").padded(),
|
||||||
just("none").padded(),
|
just("none").padded(),
|
||||||
just("range").padded(),
|
just("range").padded(),
|
||||||
|
just("struct").padded(),
|
||||||
just("str").padded(),
|
just("str").padded(),
|
||||||
just("loop").padded(),
|
just("loop").padded(),
|
||||||
just("while").padded(),
|
just("while").padded(),
|
||||||
|
@ -417,7 +417,27 @@ pub fn parser<'src>() -> impl Parser<
|
|||||||
.with_position(state.span())
|
.with_position(state.span())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let structure_field = identifier.clone().then(type_specification.clone());
|
||||||
|
|
||||||
|
let structure_definition = just(Token::Keyword("struct"))
|
||||||
|
.ignore_then(identifier.clone())
|
||||||
|
.then(
|
||||||
|
structure_field
|
||||||
|
.separated_by(just(Token::Control(Control::Comma)))
|
||||||
|
.allow_trailing()
|
||||||
|
.collect()
|
||||||
|
.delimited_by(
|
||||||
|
just(Token::Control(Control::CurlyOpen)),
|
||||||
|
just(Token::Control(Control::CurlyClose)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map_with(|(name, fields), state| {
|
||||||
|
Statement::StructureDefinition(StructureDefinition::new(name, fields))
|
||||||
|
.with_position(state.span())
|
||||||
|
});
|
||||||
|
|
||||||
choice((
|
choice((
|
||||||
|
structure_definition,
|
||||||
if_else,
|
if_else,
|
||||||
assignment,
|
assignment,
|
||||||
expression_statement,
|
expression_statement,
|
||||||
@ -438,6 +458,36 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn structure_definition() {
|
||||||
|
assert_eq!(
|
||||||
|
parse(
|
||||||
|
&lex("
|
||||||
|
struct Foo {
|
||||||
|
bar : int,
|
||||||
|
baz : str,
|
||||||
|
}
|
||||||
|
")
|
||||||
|
.unwrap()
|
||||||
|
)
|
||||||
|
.unwrap()[0]
|
||||||
|
.node,
|
||||||
|
Statement::StructureDefinition(StructureDefinition::new(
|
||||||
|
Identifier::new("Foo"),
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
Identifier::new("bar"),
|
||||||
|
Type::Integer.with_position((64, 67))
|
||||||
|
),
|
||||||
|
(
|
||||||
|
Identifier::new("baz"),
|
||||||
|
Type::String.with_position((99, 102))
|
||||||
|
),
|
||||||
|
]
|
||||||
|
))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn map_index() {
|
fn map_index() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
Loading…
Reference in New Issue
Block a user