1
0

Compare commits

...

2 Commits

Author SHA1 Message Date
06f3a9b746 Remove built-in value statements 2024-08-07 15:53:43 -04:00
cda0203242 Replace spans with a generic type 2024-08-07 15:47:37 -04:00
5 changed files with 75 additions and 82 deletions

View File

@ -5,45 +5,44 @@ use std::{
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{Identifier, ReservedIdentifier, Span, Type, Value}; use crate::{Identifier, ReservedIdentifier, Type, Value};
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct AbstractSyntaxTree { pub struct AbstractSyntaxTree<P> {
pub nodes: VecDeque<Node>, pub nodes: VecDeque<Node<P>>,
} }
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Node { pub struct Node<P> {
pub statement: Statement, pub statement: Statement<P>,
pub span: Span, pub position: P,
} }
impl Node { impl<P> Node<P> {
pub fn new(operation: Statement, span: Span) -> Self { pub fn new(operation: Statement<P>, position: P) -> Self {
Self { Self {
statement: operation, statement: operation,
span, position,
} }
} }
} }
impl Display for Node { impl<P> Display for Node<P> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.statement) write!(f, "{}", self.statement)
} }
} }
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Statement { pub enum Statement<P> {
// Top-level statements // Top-level statements
Assign(Box<Node>, Box<Node>), Assign(Box<Node<P>>, Box<Node<P>>),
// Expressions // Expressions
Add(Box<Node>, Box<Node>), Add(Box<Node<P>>, Box<Node<P>>),
BuiltInValue(Box<Node>), PropertyAccess(Box<Node<P>>, Box<Node<P>>),
PropertyAccess(Box<Node>, Box<Node>), List(Vec<Node<P>>),
List(Vec<Node>), Multiply(Box<Node<P>>, Box<Node<P>>),
Multiply(Box<Node>, Box<Node>),
// Hard-coded values // Hard-coded values
Constant(Value), Constant(Value),
@ -51,12 +50,11 @@ pub enum Statement {
ReservedIdentifier(ReservedIdentifier), ReservedIdentifier(ReservedIdentifier),
} }
impl Statement { impl<P> Statement<P> {
pub fn expected_type(&self, variables: &HashMap<Identifier, Value>) -> Option<Type> { pub fn expected_type(&self, variables: &HashMap<Identifier, Value>) -> Option<Type> {
match self { match self {
Statement::Add(left, _) => left.statement.expected_type(variables), Statement::Add(left, _) => left.statement.expected_type(variables),
Statement::Assign(_, _) => None, Statement::Assign(_, _) => None,
Statement::BuiltInValue(reserved) => reserved.statement.expected_type(variables),
Statement::Constant(value) => Some(value.r#type(variables)), Statement::Constant(value) => Some(value.r#type(variables)),
Statement::Identifier(identifier) => variables Statement::Identifier(identifier) => variables
.get(identifier) .get(identifier)
@ -72,12 +70,11 @@ impl Statement {
} }
} }
impl Display for Statement { impl<P> Display for Statement<P> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Statement::Assign(left, right) => write!(f, "{left} = {right}"), Statement::Assign(left, right) => write!(f, "{left} = {right}"),
Statement::Add(left, right) => write!(f, "{left} + {right}"), Statement::Add(left, right) => write!(f, "{left} + {right}"),
Statement::BuiltInValue(reserved) => write!(f, "{reserved}"),
Statement::PropertyAccess(left, right) => write!(f, "{left}.{right}"), Statement::PropertyAccess(left, right) => write!(f, "{left}.{right}"),
Statement::List(nodes) => { Statement::List(nodes) => {
write!(f, "[")?; write!(f, "[")?;

View File

@ -22,10 +22,10 @@ use crate::{AbstractSyntaxTree, Identifier, Node, Statement, Type, Value};
/// ///
/// assert!(result.is_err()); /// assert!(result.is_err());
/// ``` /// ```
pub fn analyze( pub fn analyze<P: Clone>(
abstract_tree: &AbstractSyntaxTree, abstract_tree: &AbstractSyntaxTree<P>,
variables: &HashMap<Identifier, Value>, variables: &HashMap<Identifier, Value>,
) -> Result<(), AnalyzerError> { ) -> Result<(), AnalyzerError<P>> {
let analyzer = Analyzer::new(abstract_tree, variables); let analyzer = Analyzer::new(abstract_tree, variables);
analyzer.analyze() analyzer.analyze()
@ -44,14 +44,14 @@ pub fn analyze(
/// let result = analyzer.analyze(); /// let result = analyzer.analyze();
/// ///
/// assert!(result.is_err()); /// assert!(result.is_err());
pub struct Analyzer<'a> { pub struct Analyzer<'a, P> {
abstract_tree: &'a AbstractSyntaxTree, abstract_tree: &'a AbstractSyntaxTree<P>,
variables: &'a HashMap<Identifier, Value>, variables: &'a HashMap<Identifier, Value>,
} }
impl<'a> Analyzer<'a> { impl<'a, P: Clone> Analyzer<'a, P> {
pub fn new( pub fn new(
abstract_tree: &'a AbstractSyntaxTree, abstract_tree: &'a AbstractSyntaxTree<P>,
variables: &'a HashMap<Identifier, Value>, variables: &'a HashMap<Identifier, Value>,
) -> Self { ) -> Self {
Self { Self {
@ -60,7 +60,7 @@ impl<'a> Analyzer<'a> {
} }
} }
pub fn analyze(&self) -> Result<(), AnalyzerError> { pub fn analyze(&self) -> Result<(), AnalyzerError<P>> {
for node in &self.abstract_tree.nodes { for node in &self.abstract_tree.nodes {
self.analyze_node(node)?; self.analyze_node(node)?;
} }
@ -68,7 +68,7 @@ impl<'a> Analyzer<'a> {
Ok(()) Ok(())
} }
fn analyze_node(&self, node: &Node) -> Result<(), AnalyzerError> { fn analyze_node(&self, node: &Node<P>) -> Result<(), AnalyzerError<P>> {
match &node.statement { match &node.statement {
Statement::Add(left, right) => { Statement::Add(left, right) => {
if let Some(Type::Integer) | Some(Type::Float) = if let Some(Type::Integer) | Some(Type::Float) =
@ -103,9 +103,6 @@ impl<'a> Analyzer<'a> {
self.analyze_node(right)?; self.analyze_node(right)?;
} }
Statement::BuiltInValue(node) => {
self.analyze_node(node)?;
}
Statement::Constant(_) => {} Statement::Constant(_) => {}
Statement::Identifier(_) => { Statement::Identifier(_) => {
return Err(AnalyzerError::UnexpectedIdentifier { return Err(AnalyzerError::UnexpectedIdentifier {
@ -160,10 +157,10 @@ impl<'a> Analyzer<'a> {
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum AnalyzerError { pub enum AnalyzerError<P> {
ExpectedIdentifier { actual: Node }, ExpectedIdentifier { actual: Node<P> },
ExpectedIntegerOrFloat { actual: Node }, ExpectedIntegerOrFloat { actual: Node<P> },
UnexpectedIdentifier { identifier: Node }, UnexpectedIdentifier { identifier: Node<P> },
} }
#[cfg(test)] #[cfg(test)]

View File

@ -23,20 +23,20 @@ use crate::{AbstractSyntaxTree, LexError, Lexer, Node, Span, Statement, Token, V
/// statement: Statement::Assign( /// statement: Statement::Assign(
/// Box::new(Node { /// Box::new(Node {
/// statement: Statement::Identifier("x".into()), /// statement: Statement::Identifier("x".into()),
/// span: (0, 1), /// position: (0, 1),
/// }), /// }),
/// Box::new(Node { /// Box::new(Node {
/// statement: Statement::Constant(Value::integer(42)), /// statement: Statement::Constant(Value::integer(42)),
/// span: (4, 6), /// position: (4, 6),
/// }) /// })
/// ), /// ),
/// span: (0, 6), /// position: (0, 6),
/// } /// }
/// ].into(), /// ].into(),
/// }), /// }),
/// ); /// );
/// ``` /// ```
pub fn parse(input: &str) -> Result<AbstractSyntaxTree, ParseError> { pub fn parse(input: &str) -> Result<AbstractSyntaxTree<Span>, ParseError> {
let lexer = Lexer::new(input); let lexer = Lexer::new(input);
let mut parser = Parser::new(lexer); let mut parser = Parser::new(lexer);
let mut nodes = VecDeque::new(); let mut nodes = VecDeque::new();
@ -77,19 +77,19 @@ pub fn parse(input: &str) -> Result<AbstractSyntaxTree, ParseError> {
/// ///
/// assert_eq!( /// assert_eq!(
/// nodes, /// nodes,
/// Into::<VecDeque<Node>>::into([ /// Into::<VecDeque<Node<Span>>>::into([
/// Node { /// Node {
/// statement: Statement::Assign( /// statement: Statement::Assign(
/// Box::new(Node { /// Box::new(Node {
/// statement: Statement::Identifier("x".into()), /// statement: Statement::Identifier("x".into()),
/// span: (0, 1), /// position: (0, 1),
/// }), /// }),
/// Box::new(Node { /// Box::new(Node {
/// statement: Statement::Constant(Value::integer(42)), /// statement: Statement::Constant(Value::integer(42)),
/// span: (4, 6), /// position: (4, 6),
/// }) /// })
/// ), /// ),
/// span: (0, 6), /// position: (0, 6),
/// } /// }
/// ]), /// ]),
/// ); /// );
@ -107,7 +107,7 @@ impl<'src> Parser<'src> {
Parser { lexer, current } Parser { lexer, current }
} }
pub fn parse(&mut self) -> Result<Node, ParseError> { pub fn parse(&mut self) -> Result<Node<Span>, ParseError> {
self.parse_node(0) self.parse_node(0)
} }
@ -121,9 +121,9 @@ impl<'src> Parser<'src> {
Ok(()) Ok(())
} }
fn parse_node(&mut self, precedence: u8) -> Result<Node, ParseError> { fn parse_node(&mut self, precedence: u8) -> Result<Node<Span>, ParseError> {
let left_node = self.parse_primary()?; let left_node = self.parse_primary()?;
let left_start = left_node.span.0; let left_start = left_node.position.0;
if precedence < self.current_precedence() { if precedence < self.current_precedence() {
match &self.current { match &self.current {
@ -131,7 +131,7 @@ impl<'src> Parser<'src> {
self.next_token()?; self.next_token()?;
let right_node = self.parse_node(self.current_precedence())?; let right_node = self.parse_node(self.current_precedence())?;
let right_end = right_node.span.1; let right_end = right_node.position.1;
return Ok(Node::new( return Ok(Node::new(
Statement::Add(Box::new(left_node), Box::new(right_node)), Statement::Add(Box::new(left_node), Box::new(right_node)),
@ -142,7 +142,7 @@ impl<'src> Parser<'src> {
self.next_token()?; self.next_token()?;
let right_node = self.parse_node(self.current_precedence())?; let right_node = self.parse_node(self.current_precedence())?;
let right_end = right_node.span.1; let right_end = right_node.position.1;
return Ok(Node::new( return Ok(Node::new(
Statement::Multiply(Box::new(left_node), Box::new(right_node)), Statement::Multiply(Box::new(left_node), Box::new(right_node)),
@ -153,7 +153,7 @@ impl<'src> Parser<'src> {
self.next_token()?; self.next_token()?;
let right_node = self.parse_node(self.current_precedence())?; let right_node = self.parse_node(self.current_precedence())?;
let right_end = right_node.span.1; let right_end = right_node.position.1;
return Ok(Node::new( return Ok(Node::new(
Statement::Assign(Box::new(left_node), Box::new(right_node)), Statement::Assign(Box::new(left_node), Box::new(right_node)),
@ -164,7 +164,7 @@ impl<'src> Parser<'src> {
self.next_token()?; self.next_token()?;
let right_node = self.parse_node(self.current_precedence())?; let right_node = self.parse_node(self.current_precedence())?;
let right_end = right_node.span.1; let right_end = right_node.position.1;
return Ok(Node::new( return Ok(Node::new(
Statement::PropertyAccess(Box::new(left_node), Box::new(right_node)), Statement::PropertyAccess(Box::new(left_node), Box::new(right_node)),
@ -178,7 +178,7 @@ impl<'src> Parser<'src> {
Ok(left_node) Ok(left_node)
} }
fn parse_primary(&mut self) -> Result<Node, ParseError> { fn parse_primary(&mut self) -> Result<Node<Span>, ParseError> {
match self.current.clone() { match self.current.clone() {
(Token::Boolean(boolean), span) => { (Token::Boolean(boolean), span) => {
self.next_token()?; self.next_token()?;

View File

@ -539,7 +539,7 @@ pub struct Function {
pub name: Identifier, pub name: Identifier,
pub type_parameters: Option<Vec<Type>>, pub type_parameters: Option<Vec<Type>>,
pub value_parameters: Option<Vec<(Identifier, Type)>>, pub value_parameters: Option<Vec<(Identifier, Type)>>,
pub body: Vec<Statement>, pub body: Vec<Statement<()>>,
} }
impl Function { impl Function {

View File

@ -8,7 +8,7 @@ use crate::{
pub fn run( pub fn run(
input: &str, input: &str,
variables: &mut HashMap<Identifier, Value>, variables: &mut HashMap<Identifier, Value>,
) -> Result<Option<Value>, VmError> { ) -> Result<Option<Value>, VmError<Span>> {
let abstract_syntax_tree = parse(input)?; let abstract_syntax_tree = parse(input)?;
let analyzer = Analyzer::new(&abstract_syntax_tree, variables); let analyzer = Analyzer::new(&abstract_syntax_tree, variables);
@ -19,19 +19,19 @@ pub fn run(
vm.run(variables) vm.run(variables)
} }
pub struct Vm { pub struct Vm<P> {
abstract_tree: AbstractSyntaxTree, abstract_tree: AbstractSyntaxTree<P>,
} }
impl Vm { impl<P: Copy> Vm<P> {
pub fn new(abstract_tree: AbstractSyntaxTree) -> Self { pub fn new(abstract_tree: AbstractSyntaxTree<P>) -> Self {
Self { abstract_tree } Self { abstract_tree }
} }
pub fn run( pub fn run(
&mut self, &mut self,
variables: &mut HashMap<Identifier, Value>, variables: &mut HashMap<Identifier, Value>,
) -> Result<Option<Value>, VmError> { ) -> Result<Option<Value>, VmError<P>> {
let mut previous_value = None; let mut previous_value = None;
while let Some(node) = self.abstract_tree.nodes.pop_front() { while let Some(node) = self.abstract_tree.nodes.pop_front() {
@ -43,16 +43,15 @@ impl Vm {
fn run_node( fn run_node(
&self, &self,
node: Node, node: Node<P>,
variables: &mut HashMap<Identifier, Value>, variables: &mut HashMap<Identifier, Value>,
) -> Result<Option<Value>, VmError> { ) -> Result<Option<Value>, VmError<P>> {
match node.statement { match node.statement {
Statement::BuiltInValue(node) => self.run_node(*node, variables),
Statement::Constant(value) => Ok(Some(value.clone())), Statement::Constant(value) => Ok(Some(value.clone())),
Statement::Identifier(_) => Ok(None), Statement::Identifier(_) => Ok(None),
Statement::ReservedIdentifier(_) => Ok(None), Statement::ReservedIdentifier(_) => Ok(None),
Statement::Add(left, right) => { Statement::Add(left, right) => {
let left_span = left.span; let left_span = left.position;
let left = if let Some(value) = self.run_node(*left, variables)? { let left = if let Some(value) = self.run_node(*left, variables)? {
value value
} else { } else {
@ -60,7 +59,7 @@ impl Vm {
position: left_span, position: left_span,
}); });
}; };
let right_span = right.span; let right_span = right.position;
let right = if let Some(value) = self.run_node(*right, variables)? { let right = if let Some(value) = self.run_node(*right, variables)? {
value value
} else { } else {
@ -77,10 +76,10 @@ impl Vm {
identifier identifier
} else { } else {
return Err(VmError::ExpectedIdentifier { return Err(VmError::ExpectedIdentifier {
position: left.span, position: left.position,
}); });
}; };
let right_span = right.span; let right_span = right.position;
let value = if let Some(value) = self.run_node(*right, variables)? { let value = if let Some(value) = self.run_node(*right, variables)? {
value value
} else { } else {
@ -97,20 +96,20 @@ impl Vm {
let values = nodes let values = nodes
.into_iter() .into_iter()
.map(|node| { .map(|node| {
let span = node.span; let span = node.position;
if let Some(value) = self.run_node(node, variables)? { if let Some(value) = self.run_node(node, variables)? {
Ok(value) Ok(value)
} else { } else {
Err(VmError::ExpectedValue { position: span }) Err(VmError::ExpectedValue { position: span })
} }
}) })
.collect::<Result<Vec<Value>, VmError>>()?; .collect::<Result<Vec<Value>, VmError<P>>>()?;
Ok(Some(Value::list(values))) Ok(Some(Value::list(values)))
} }
Statement::Multiply(_, _) => todo!(), Statement::Multiply(_, _) => todo!(),
Statement::PropertyAccess(left, right) => { Statement::PropertyAccess(left, right) => {
let left_span = left.span; let left_span = left.position;
let left = if let Some(value) = self.run_node(*left, variables)? { let left = if let Some(value) = self.run_node(*left, variables)? {
value value
} else { } else {
@ -118,7 +117,7 @@ impl Vm {
position: left_span, position: left_span,
}); });
}; };
let right_span = right.span; let right_span = right.position;
if let Statement::ReservedIdentifier(reserved) = &right.statement { if let Statement::ReservedIdentifier(reserved) = &right.statement {
match reserved { match reserved {
@ -170,33 +169,33 @@ impl Vm {
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum VmError { pub enum VmError<P> {
AnaylyzerError(AnalyzerError), AnaylyzerError(AnalyzerError<P>),
ParseError(ParseError), ParseError(ParseError),
ValueError(ValueError), ValueError(ValueError),
// Anaylsis Failures // Anaylsis Failures
// These should be prevented by running the analyzer before the VM // These should be prevented by running the analyzer before the VM
ExpectedIdentifier { position: Span }, ExpectedIdentifier { position: P },
ExpectedIdentifierOrInteger { position: Span }, ExpectedIdentifierOrInteger { position: P },
ExpectedInteger { position: Span }, ExpectedInteger { position: P },
ExpectedList { position: Span }, ExpectedList { position: P },
ExpectedValue { position: Span }, ExpectedValue { position: P },
} }
impl From<AnalyzerError> for VmError { impl<P> From<AnalyzerError<P>> for VmError<P> {
fn from(error: AnalyzerError) -> Self { fn from(error: AnalyzerError<P>) -> Self {
Self::AnaylyzerError(error) Self::AnaylyzerError(error)
} }
} }
impl From<ParseError> for VmError { impl<P> From<ParseError> for VmError<P> {
fn from(error: ParseError) -> Self { fn from(error: ParseError) -> Self {
Self::ParseError(error) Self::ParseError(error)
} }
} }
impl From<ValueError> for VmError { impl<P> From<ValueError> for VmError<P> {
fn from(error: ValueError) -> Self { fn from(error: ValueError) -> Self {
Self::ValueError(error) Self::ValueError(error)
} }