parser works for var decl with assignment
This commit is contained in:
		
					parent
					
						
							
								6756d286f9
							
						
					
				
			
			
				commit
				
					
						8ce2b5aad2
					
				
			
		
					 6 changed files with 139 additions and 124 deletions
				
			
		|  | @ -1,11 +1,4 @@ | |||
| use std::rc::Rc; | ||||
| 
 | ||||
| use chumsky::span::Span; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /// Abstract Syntax Tree
 | ||||
| pub type BlockStatement = Vec<Statement>; | ||||
| use crate::language_frontend::abstract_syntax_tree::definitions::*; | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum Expr { | ||||
|  | @ -51,105 +44,3 @@ pub enum Expr { | |||
|     }, | ||||
|     Error, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub struct FunctionCall { | ||||
|     pub name: Rc<str>, | ||||
|     pub parameters: Vec<Expr>, | ||||
|     pub(crate) args: Vec<String>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum BinaryOp { | ||||
|     Multiply, | ||||
|     Divide, | ||||
|     Add, | ||||
|     Substract, | ||||
| 
 | ||||
|     Equals, | ||||
|     NotEquals, | ||||
|     Less, | ||||
|     LessEquals, | ||||
|     Greater, | ||||
|     GreaterEquals, | ||||
| 
 | ||||
|     And, | ||||
|     Or, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum UnaryOp { | ||||
|     Not, | ||||
|     Minus, | ||||
|     Plus, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum Literal { | ||||
|     UnsignedInteger(u64), | ||||
|     Bool(bool), | ||||
|     Char(char), | ||||
|     String(Rc<str>), | ||||
|     Int(i64), | ||||
|     Float(f64), | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub struct Ident(pub Rc<str>); | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum Statement { | ||||
|     Var(Ident, Option<Type>) | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub struct While { | ||||
|     pub condition: Expr, | ||||
|     pub body: BlockStatement, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub struct Condition { | ||||
|     pub condition: Expr, | ||||
|     pub if_body: BlockStatement, | ||||
|     pub else_body: Option<BlockStatement>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum Type { | ||||
|     UnsignedInteger, | ||||
|     SignedInteger, | ||||
|     Bool, | ||||
|     Char, | ||||
|     String, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum Value { | ||||
|     UnsignedInteger(u32), | ||||
|     SignedInteger(i32), | ||||
|     Bool(bool), | ||||
|     Char(char), | ||||
|     String(String), | ||||
| } | ||||
| 
 | ||||
| impl Value { | ||||
|     pub fn is_type(&self, ty: &Type) -> bool { | ||||
|         match (ty, self) { | ||||
|             (Type::Bool, Value::Bool(_)) => true, | ||||
|             (Type::Char, Value::Char(_)) => true, | ||||
|             (Type::SignedInteger, Value::SignedInteger(_)) => true, | ||||
|             (Type::UnsignedInteger, Value::UnsignedInteger(_)) => true, | ||||
|             (Type::String, Value::String(_)) => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub struct Function { | ||||
|     pub name: Rc<str>, | ||||
|     pub params: Vec<(Ident, Type)>, | ||||
|     pub return_type: Option<Type>, | ||||
|     pub body: Vec<Statement>, | ||||
| } | ||||
							
								
								
									
										110
									
								
								src/language_frontend/abstract_syntax_tree/definitions.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/language_frontend/abstract_syntax_tree/definitions.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,110 @@ | |||
| use std::{ops::Range, rc::Rc}; | ||||
| 
 | ||||
| use crate::language_frontend::abstract_syntax_tree::ast::Expr; | ||||
| 
 | ||||
| /// Abstract Syntax Tree
 | ||||
| pub type BlockStatement = Vec<Statement>; | ||||
| 
 | ||||
| pub type Span = Range<usize>; | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum Statement { | ||||
|     Var(Ident, Option<Type>) | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum BinaryOp { | ||||
|     Multiply, | ||||
|     Divide, | ||||
|     Add, | ||||
|     Substract, | ||||
| 
 | ||||
|     Equals, | ||||
|     NotEquals, | ||||
|     Less, | ||||
|     LessEquals, | ||||
|     Greater, | ||||
|     GreaterEquals, | ||||
| 
 | ||||
|     And, | ||||
|     Or, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum UnaryOp { | ||||
|     Not, | ||||
|     Minus, | ||||
|     Plus, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum Literal { | ||||
|     UnsignedInteger(u64), | ||||
|     Bool(bool), | ||||
|     Char(char), | ||||
|     String(Rc<str>), | ||||
|     Int(i64), | ||||
|     Float(f64), | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum Type { | ||||
|     UnsignedInteger, | ||||
|     SignedInteger, | ||||
|     Bool, | ||||
|     Char, | ||||
|     String, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub enum Value { | ||||
|     UnsignedInteger(u32), | ||||
|     SignedInteger(i32), | ||||
|     Bool(bool), | ||||
|     Char(char), | ||||
|     String(String), | ||||
| } | ||||
| 
 | ||||
| impl Value { | ||||
|     pub fn is_type(&self, ty: &Type) -> bool { | ||||
|         match (ty, self) { | ||||
|             (Type::Bool, Value::Bool(_)) => true, | ||||
|             (Type::Char, Value::Char(_)) => true, | ||||
|             (Type::SignedInteger, Value::SignedInteger(_)) => true, | ||||
|             (Type::UnsignedInteger, Value::UnsignedInteger(_)) => true, | ||||
|             (Type::String, Value::String(_)) => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------
 | ||||
| //      Structs
 | ||||
| //---------------------------------------
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub struct Ident(pub Rc<str>); | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub struct While { | ||||
|     pub condition: Expr, | ||||
|     pub body: BlockStatement, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub struct Condition { | ||||
|     pub condition: Expr, | ||||
|     pub if_body: BlockStatement, | ||||
|     pub else_body: Option<BlockStatement>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub struct Function { | ||||
|     pub name: Rc<str>, | ||||
|     pub params: Vec<(Ident, Type)>, | ||||
|     pub return_type: Option<Type>, | ||||
|     pub body: Vec<Statement>, | ||||
| } | ||||
| 
 | ||||
|  | @ -1,2 +1,3 @@ | |||
| pub mod ast; | ||||
| pub mod definitions; | ||||
| pub mod parser; | ||||
|  |  | |||
|  | @ -3,16 +3,14 @@ use chumsky::{ | |||
| }; | ||||
| use logos::{source, Logos}; | ||||
| 
 | ||||
| use crate::language_frontend::{abstract_syntax_tree::ast::{BinaryOp, Expr, UnaryOp}, lexer::tokens::{self, Token}}; | ||||
| use crate::language_frontend::{abstract_syntax_tree::{ast::Expr, definitions::*}, lexer::tokens::Token}; | ||||
| 
 | ||||
| // goal of parsing is to construct an abstract syntax tree
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| pub fn parse(source: &str) ->Result<Vec<Expr>, Vec<Rich<'_, Token>>> { | ||||
|     let token_iter = Token::lexer(source).spanned().map(|(token, span)| (token.unwrap_or(Token::Error), span.into())); | ||||
| 
 | ||||
|     let end_of_input: SimpleSpan = (source.len()..source.len()).into(); | ||||
|     let end_of_input: SimpleSpan = (0..source.len()).into(); | ||||
|     let token_stream = Stream::from_iter(token_iter) | ||||
|         // Tell chumsky to split the (Token, SimpleSpan) stream into its parts so that it can handle the spans for us
 | ||||
|         // This involves giving chumsky an 'end of input' span: we just use a zero-width span at the end of the string
 | ||||
|  | @ -37,7 +35,6 @@ where | |||
| 
 | ||||
|         block.with_ctx(0) | ||||
|     }); | ||||
| 
 | ||||
|     */ | ||||
| 
 | ||||
|     let expr = recursive(|expr| { | ||||
|  | @ -93,3 +90,10 @@ where | |||
|     decl.repeated().collect() | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
| 
 | ||||
|   
 | ||||
| } | ||||
|  | @ -3,7 +3,7 @@ use std::fmt; | |||
| use logos::{Logos}; | ||||
| 
 | ||||
| #[derive(Logos, Debug, Clone, PartialEq)] | ||||
| #[regex(r"[ \t\f]+", logos::skip)] | ||||
| #[regex(r"[\t\f]+", logos::skip)] | ||||
| pub enum Token { | ||||
|     // Identifier
 | ||||
|     #[regex(r"[a-zA-Z_][a-zA-Z0-9_]*", |lex| lex.slice().to_owned())] | ||||
|  |  | |||
							
								
								
									
										25
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								src/main.rs
									
										
									
									
									
								
							|  | @ -1,12 +1,14 @@ | |||
| use chumsky::input::{Input, Stream}; | ||||
| use chumsky::prelude::end; | ||||
| use chumsky::Parser; | ||||
| use logos::Logos; | ||||
| 
 | ||||
| use crate::language_frontend::abstract_syntax_tree::parser::parse; | ||||
| 
 | ||||
| mod language_frontend; | ||||
| 
 | ||||
| use crate::{ | ||||
|     language_frontend::lexer::tokens::Token, language_frontend::abstract_syntax_tree::parser::parse}; | ||||
| 
 | ||||
| use crate::language_frontend::abstract_syntax_tree::ast::{Expr};  
 | ||||
| 
 | ||||
| /* | ||||
| Simple Compiler -> 4 Stages: | ||||
| - lex | ||||
|  | @ -24,17 +26,24 @@ fn main() { | |||
| 
 | ||||
|     println!("{:?}", sourcecode); | ||||
| 
 | ||||
|     /* | ||||
|     
 | ||||
|     let lexer =  Token::lexer(&sourcecode) | ||||
|         .spanned(); | ||||
|         //.collect::<Vec<_>>();
 | ||||
|         .spanned() | ||||
|         .collect::<Vec<_>>(); | ||||
|     
 | ||||
|     for token in lexer { | ||||
|         println!("{:?}", token); | ||||
|     } 
 | ||||
|     */ 
 | ||||
|     
 | ||||
|     match parse(&sourcecode) { | ||||
|     let token_iter = Token::lexer(&sourcecode).spanned().map(|(tok, span)| tok.map(|t| (t, span))).filter_map(Result::ok); | ||||
| 
 | ||||
|     let token_stream = Stream::from_iter(token_iter) | ||||
|         // Tell chumsky to split the (Token, SimpleSpan) stream into its parts so that it can handle the spans for us
 | ||||
|         // This involves giving chumsky an 'end of input' span: we just use a zero-width span at the end of the string
 | ||||
|         .map((0..sourcecode.len()).into(), |(t, s): (_, _)| (t, s)); | ||||
| 
 | ||||
| 
 | ||||
|     match parse(&sourcecode)  { | ||||
|         Ok(res) => println!("{:?}", res), | ||||
|         Err(e) => { | ||||
|             panic!("{:#?}", e) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue