From 94f0b0c92d6ad7f1d9c847e909b9858484919972 Mon Sep 17 00:00:00 2001 From: Araozu Date: Thu, 7 Sep 2023 20:50:51 -0500 Subject: [PATCH] Refactor AST location --- .gitignore | 1 + src/codegen/binding.rs | 4 +- src/codegen/expression.rs | 4 +- src/codegen/mod.rs | 4 +- src/codegen/module_ast.rs | 4 +- src/error_handling/syntax_error.rs | 2 +- src/lexic/token.rs | 109 ++++++++++++++++++++++++++++ src/main.rs | 2 - src/semantic/datatype.rs | 61 ---------------- src/semantic/guidance.md | 15 ---- src/semantic/mod.rs | 101 -------------------------- src/semantic/type_check.rs | 62 ---------------- src/{ast_types.rs => syntax/ast.rs} | 0 src/syntax/binding.rs | 2 +- src/syntax/expression.rs | 2 +- src/syntax/mod.rs | 7 +- src/utils/mod.rs | 1 + 17 files changed, 125 insertions(+), 256 deletions(-) create mode 100644 .gitignore create mode 100755 src/lexic/token.rs delete mode 100644 src/semantic/datatype.rs delete mode 100644 src/semantic/guidance.md delete mode 100644 src/semantic/mod.rs delete mode 100644 src/semantic/type_check.rs rename src/{ast_types.rs => syntax/ast.rs} (100%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb5a316 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target diff --git a/src/codegen/binding.rs b/src/codegen/binding.rs index fd13d61..3d44c33 100644 --- a/src/codegen/binding.rs +++ b/src/codegen/binding.rs @@ -1,5 +1,5 @@ use super::Transpilable; -use crate::ast_types::Binding; +use crate::syntax::ast::Binding; impl Transpilable for Binding { /// Transpiles val and var bindings into JS. @@ -22,7 +22,7 @@ impl Transpilable for Binding { #[cfg(test)] mod tests { use super::*; - use crate::ast_types::{Binding, Expression, ValBinding}; + use crate::syntax::ast::{Binding, Expression, ValBinding}; #[test] fn binding_should_transpile() { diff --git a/src/codegen/expression.rs b/src/codegen/expression.rs index c523af1..f4d01a3 100644 --- a/src/codegen/expression.rs +++ b/src/codegen/expression.rs @@ -1,5 +1,5 @@ use super::Transpilable; -use crate::ast_types::Expression; +use crate::syntax::ast::Expression; impl Transpilable for Expression { /// Transpiles an Expression to JS @@ -24,7 +24,7 @@ impl Transpilable for Expression { #[cfg(test)] mod tests { use super::*; - use crate::ast_types::Expression; + use crate::syntax::ast::Expression; #[test] fn should_transpile_number() { diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 66da241..db897b7 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1,4 +1,4 @@ -use super::ast_types::ModuleAST; +use crate::syntax::ast::ModuleAST; mod binding; mod expression; @@ -25,7 +25,7 @@ mod tests { fn should_codegen_1() { let input = String::from("val id = 322"); let tokens = lexic::get_tokens(&input).unwrap(); - let mut ast = syntax::construct_ast(&tokens).unwrap(); + let ast = syntax::construct_ast(&tokens).unwrap(); let out_str = codegen(&ast); diff --git a/src/codegen/module_ast.rs b/src/codegen/module_ast.rs index 6e2afd7..87d0581 100644 --- a/src/codegen/module_ast.rs +++ b/src/codegen/module_ast.rs @@ -1,5 +1,5 @@ use super::Transpilable; -use crate::ast_types::ModuleAST; +use crate::syntax::ast::ModuleAST; impl Transpilable for ModuleAST { /// Transpiles the whole AST into JS, using this same trait on the @@ -18,7 +18,7 @@ impl Transpilable for ModuleAST { #[cfg(test)] mod tests { use super::*; - use crate::ast_types::{Binding, Expression, ValBinding}; + use crate::syntax::ast::{Binding, Expression, ValBinding}; #[test] fn module_ast_should_transpile() { diff --git a/src/error_handling/syntax_error.rs b/src/error_handling/syntax_error.rs index 84aa777..7a57b60 100644 --- a/src/error_handling/syntax_error.rs +++ b/src/error_handling/syntax_error.rs @@ -94,7 +94,7 @@ fn get_line( mod tests { use super::*; use crate::{ - error_handling::{MistiError, PrintableError, SyntaxError}, + error_handling::{MistiError, PrintableError}, lexic::get_tokens, syntax::construct_ast, }; diff --git a/src/lexic/token.rs b/src/lexic/token.rs new file mode 100755 index 0000000..a034bfb --- /dev/null +++ b/src/lexic/token.rs @@ -0,0 +1,109 @@ +#[derive(PartialEq, Debug, Clone)] +pub enum TokenType { + Identifier, + Datatype, + Number, + String, + Operator, + LeftParen, + RightParen, + LeftBracket, + RightBracket, + LeftBrace, + RightBrace, + Semicolon, + Comment, + VAR, + VAL, + EOF, +} + +#[derive(Debug)] +pub struct Token { + pub token_type: TokenType, + // The token as a raw string + pub value: String, + /// The absolute position of this token, from the + /// start of the file + pub position: usize, +} + +impl Token { + pub fn get_end_position(&self) -> usize { + self.position + self.value.len() + } +} + +impl Token { + pub fn new_eof(position: usize) -> Token { + Token { + token_type: TokenType::EOF, + value: String::from(""), + position, + } + } + + pub fn new_number(value: String, position: usize) -> Token { + Token { + token_type: TokenType::Number, + value, + position, + } + } + + pub fn new_operator(value: String, position: usize) -> Token { + Token { + token_type: TokenType::Operator, + value, + position, + } + } + + pub fn new(value: String, position: usize, token_type: TokenType) -> Token { + Token { + token_type, + value, + position, + } + } + + pub fn new_identifier(value: String, position: usize) -> Token { + Token { + token_type: TokenType::Identifier, + value, + position, + } + } + + pub fn new_string(value: String, position: usize) -> Token { + Token { + token_type: TokenType::String, + value, + position, + } + } + + pub fn new_semicolon(position: usize) -> Token { + Token { + token_type: TokenType::Semicolon, + value: String::from(";"), + position, + } + } + + pub fn new_datatype(value: String, position: usize) -> Token { + Token { + token_type: TokenType::Datatype, + value, + position, + } + } + + pub fn new_comment(value: String, position: usize) -> Token { + Token { + token_type: TokenType::Comment, + value, + position, + } + } +} diff --git a/src/main.rs b/src/main.rs index a58114d..9c3f627 100755 --- a/src/main.rs +++ b/src/main.rs @@ -8,8 +8,6 @@ mod file; mod syntax; // Module to handle syntactic analysis mod lexic; -// Defines the AST -mod ast_types; // Transforms an AST to JS mod codegen; mod utils; diff --git a/src/semantic/datatype.rs b/src/semantic/datatype.rs deleted file mode 100644 index 5cc6689..0000000 --- a/src/semantic/datatype.rs +++ /dev/null @@ -1,61 +0,0 @@ -/// Represents a qualified datatype of the compiler. -/// -/// A datatype is composed of a path, e.g. `base.Str`, `base.Num` -#[derive(PartialEq)] -pub struct Datatype { - t: String, -} - -impl Datatype { - pub fn new(t: String) -> Datatype { - Datatype { t } - } - - pub fn str() -> Datatype { - Datatype { - t: String::from("base.Str"), - } - } - - pub fn num() -> Datatype { - Datatype { - t: String::from("base.Num"), - } - } - - pub fn bool() -> Datatype { - Datatype { - t: String::from("base.Bool"), - } - } - - pub fn clone(&self) -> Datatype { - Datatype { t: self.t.clone() } - } -} - -#[cfg(test)] -mod tests { - use super::Datatype; - - #[test] - fn should_create_datatype() { - let str = Datatype::new(String::from("base.Str")); - assert_eq!("base.Str", str.t); - } - - #[test] - fn should_create_primitive_datatypes() { - assert_eq!("base.Str", Datatype::str().t); - assert_eq!("base.Num", Datatype::num().t); - assert_eq!("base.Bool", Datatype::bool().t); - } - - #[test] - fn should_compare() { - let s1 = Datatype::str(); - let s2 = Datatype::str(); - - assert_eq!(true, (s1 == s2)); - } -} diff --git a/src/semantic/guidance.md b/src/semantic/guidance.md deleted file mode 100644 index bf3b39f..0000000 --- a/src/semantic/guidance.md +++ /dev/null @@ -1,15 +0,0 @@ -# Semantic analysis - -## Label checking - -- Over all the bindings: - - Resolve references with the Symbol table - - If valid, insert reference into Symbol table - -## Type checking - -TODO - -## Flow control check - -TODO diff --git a/src/semantic/mod.rs b/src/semantic/mod.rs deleted file mode 100644 index a9275b8..0000000 --- a/src/semantic/mod.rs +++ /dev/null @@ -1,101 +0,0 @@ -use super::ast_types::{Binding, ModuleAST}; -use super::symbol_table::SymbolTable; - -mod datatype; -mod type_check; - -use type_check::Typed; - -pub use datatype::Datatype; - -/// Checks the AST. In the future should return a list of errors. -pub fn check_ast<'a>(ast: &'a ModuleAST, symbol_table: &'a mut SymbolTable) { - for binding in ast.bindings.iter() { - match binding { - Binding::Val(b) => { - let datatype = b.expression.t(symbol_table); - let identifier = b.identifier; - - // TODO: check datatype of a explicit datatype, e.g. `Str val x = 322` - - symbol_table.insert(identifier.as_str(), datatype); - } - Binding::Var(b) => { - let datatype = b.expression.t(symbol_table); - let identifier = b.identifier; - - // TODO: check datatype of a explicit datatype, e.g. `Str val x = 322` - - symbol_table.insert(identifier.as_str(), datatype); - } - } - } -} - -#[cfg(test)] -mod t { - use crate::ast_types::Expression; - - use super::*; - - #[test] - fn should_insert_into_symbol_table() { - let s1 = String::from("id"); - let s2 = String::from("322"); - let binding = Binding::Val(crate::ast_types::ValBinding { - datatype: None, - identifier: &s1, - expression: Expression::Number(&s2), - }); - - let mut table = SymbolTable::new(); - - check_ast( - &ModuleAST { - bindings: vec![binding], - }, - &mut table, - ); - - assert!(table.has_id(&String::from("id"))); - assert!(table.check_type(&String::from("id"), Datatype::num())); - } - - #[test] - fn should_insert_id_reference() { - let s1 = String::from("id"); - let s2 = String::from("322"); - let binding = Binding::Val(crate::ast_types::ValBinding { - datatype: None, - identifier: &s1, - expression: Expression::Number(&s2), - }); - - let mut table = SymbolTable::new(); - - check_ast( - &ModuleAST { - bindings: vec![binding], - }, - &mut table, - ); - - let s1 = String::from("id2"); - let s2 = String::from("id"); - let binding = Binding::Val(crate::ast_types::ValBinding { - datatype: None, - identifier: &s1, - expression: Expression::Identifier(&s2), - }); - - check_ast( - &ModuleAST { - bindings: vec![binding], - }, - &mut table, - ); - - assert!(table.has_id(&String::from("id2"))); - assert!(table.check_type(&String::from("id2"), Datatype::num())); - } -} diff --git a/src/semantic/type_check.rs b/src/semantic/type_check.rs deleted file mode 100644 index 450f6ca..0000000 --- a/src/semantic/type_check.rs +++ /dev/null @@ -1,62 +0,0 @@ -use crate::{ast_types::Expression, symbol_table::SymbolTable}; - -use super::datatype::Datatype; - -pub trait Typed<'a> { - fn t(&self, symbol_table: &'a mut SymbolTable) -> Datatype; -} - -impl<'a> Typed<'a> for Expression<'a> { - /// Returns the Datatype of this Expression - fn t(&self, symbol_table: &'a mut SymbolTable) -> Datatype { - match self { - Expression::Number(_) => Datatype::num(), - Expression::String(_) => Datatype::str(), - Expression::Boolean(_) => Datatype::bool(), - Expression::Identifier(id) => { - let res = symbol_table - .get_type(id) - .expect("SEMANTIC: identifier doesn't exist in Symbol table"); - res.clone() - } - } - } -} - -#[cfg(test)] -mod t { - use super::*; - - #[test] - fn should_get_type_of_primitives() { - let mut t = SymbolTable::new(); - - let s = String::from("322"); - let exp = Expression::Number(&s); - let datatype = exp.t(&mut t); - - assert!(datatype == Datatype::num()); - - let s = String::from("hello"); - let exp = Expression::String(&s); - let datatype = exp.t(&mut t); - - assert!(datatype == Datatype::str()); - - let exp = Expression::Boolean(true); - let datatype = exp.t(&mut t); - - assert!(datatype == Datatype::bool()); - } - - #[test] - fn shold_get_type_of_existing_id() { - let mut table = SymbolTable::new(); - table.insert("my_number", Datatype::num()); - - let id = String::from("my_number"); - let exp = Expression::Identifier(&id); - - assert!(exp.t(&mut table) == Datatype::num()); - } -} diff --git a/src/ast_types.rs b/src/syntax/ast.rs similarity index 100% rename from src/ast_types.rs rename to src/syntax/ast.rs diff --git a/src/syntax/binding.rs b/src/syntax/binding.rs index cd33324..3ca4b2f 100644 --- a/src/syntax/binding.rs +++ b/src/syntax/binding.rs @@ -1,4 +1,4 @@ -use super::ast_types::{Binding, ValBinding, VarBinding}; +use super::ast::{Binding, ValBinding, VarBinding}; use super::{expression, SyntaxResult}; use crate::error_handling::SyntaxError; use crate::lexic::token::{Token, TokenType}; diff --git a/src/syntax/expression.rs b/src/syntax/expression.rs index 6c7018c..9e771a9 100644 --- a/src/syntax/expression.rs +++ b/src/syntax/expression.rs @@ -1,4 +1,4 @@ -use super::ast_types::Expression; +use super::ast::Expression; use crate::lexic::token::{Token, TokenType}; /// An expression can be: diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 244f872..1023bbc 100755 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -1,13 +1,12 @@ -use crate::ast_types::Binding; use crate::error_handling::{MistiError, SyntaxError}; mod binding; mod expression; +pub mod ast; -use super::ast_types; +use ast::{Binding, ModuleAST}; use crate::lexic::token::Token; -use ast_types::ModuleAST; pub enum SyntaxResult { /// @@ -24,7 +23,7 @@ pub enum SyntaxResult { /// Constructs the Misti AST from a vector of tokens pub fn construct_ast<'a>(tokens: &'a Vec) -> Result { let _token_amount = tokens.len(); - let mut current_pos = 0; + let current_pos = 0; match next_construct(tokens, current_pos) { SyntaxResult::Ok(module) => Ok(ModuleAST { diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 2148f98..2f52b2a 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -4,6 +4,7 @@ pub enum Result3 { None, } +#[allow(dead_code)] impl Result3 { pub fn unwrap(&self) -> &T { match self {