diff --git a/Cargo.lock b/Cargo.lock index 08911e8..f3ed27d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,14 +158,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" -[[package]] -name = "misti" -version = "0.0.5" -dependencies = [ - "clap", - "colored", -] - [[package]] name = "once_cell" version = "1.16.0" @@ -260,6 +252,14 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thp" +version = "0.0.5" +dependencies = [ + "clap", + "colored", +] + [[package]] name = "unicode-ident" version = "1.0.5" diff --git a/Cargo.toml b/Cargo.toml index 34d4a41..91c965f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,9 @@ [package] -name = "misti" +name = "thp" version = "0.0.5" edition = "2021" -[lib] -name = "misti" -path = "src/lib.rs" -test = false - # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/src/ast_types.rs b/src/ast_types.rs index e66c3eb..29ee47b 100644 --- a/src/ast_types.rs +++ b/src/ast_types.rs @@ -1,27 +1,27 @@ -pub struct ModuleAST<'a> { - pub bindings: Vec>, +pub struct ModuleAST { + pub bindings: Vec, } -pub enum Binding<'a> { - Val(ValBinding<'a>), - Var(VarBinding<'a>), +pub enum Binding { + Val(ValBinding), + Var(VarBinding), } -pub struct ValBinding<'a> { +pub struct ValBinding { pub datatype: Option, - pub identifier: &'a String, - pub expression: Expression<'a>, + pub identifier: Box, + pub expression: Expression, } -pub struct VarBinding<'a> { +pub struct VarBinding { pub datatype: Option, - pub identifier: &'a String, - pub expression: Expression<'a>, + pub identifier: Box, + pub expression: Expression, } -pub enum Expression<'a> { - Number(&'a String), - String(&'a String), +pub enum Expression { + Number(Box), + String(Box), Boolean(bool), - Identifier(&'a String), + Identifier(Box), } diff --git a/src/codegen/binding.rs b/src/codegen/binding.rs index 86c8a9c..fd13d61 100644 --- a/src/codegen/binding.rs +++ b/src/codegen/binding.rs @@ -1,7 +1,7 @@ use super::Transpilable; use crate::ast_types::Binding; -impl Transpilable for Binding<'_> { +impl Transpilable for Binding { /// Transpiles val and var bindings into JS. fn transpile(&self) -> String { match self { @@ -30,8 +30,8 @@ mod tests { let value = String::from("322"); let binding = Binding::Val(ValBinding { datatype: None, - identifier: &id, - expression: Expression::Number(&value), + identifier: Box::new(id), + expression: Expression::Number(Box::new(value)), }); let result = binding.transpile(); diff --git a/src/codegen/expression.rs b/src/codegen/expression.rs index 02d6b43..c523af1 100644 --- a/src/codegen/expression.rs +++ b/src/codegen/expression.rs @@ -1,7 +1,7 @@ use super::Transpilable; use crate::ast_types::Expression; -impl Transpilable for Expression<'_> { +impl Transpilable for Expression { /// Transpiles an Expression to JS /// /// Right now the expressions in the grammar are: @@ -11,12 +11,12 @@ impl Transpilable for Expression<'_> { /// - Identifier fn transpile(&self) -> String { match self { - Expression::Number(value) => String::from(*value), + Expression::Number(value) => format!("{}", value), Expression::String(value) => { format!("\"{}\"", *value) } Expression::Boolean(value) => String::from(if *value { "true" } else { "false" }), - Expression::Identifier(value) => String::from(*value), + Expression::Identifier(value) => format!("{}", *value), } } } @@ -29,7 +29,7 @@ mod tests { #[test] fn should_transpile_number() { let str = String::from("42"); - let exp = Expression::Number(&str); + let exp = Expression::Number(Box::new(str)); let result = exp.transpile(); assert_eq!("42", result); @@ -38,7 +38,7 @@ mod tests { #[test] fn should_transpile_string() { let str = String::from("Hello world"); - let exp = Expression::String(&str); + let exp = Expression::String(Box::new(str)); let result = exp.transpile(); assert_eq!("\"Hello world\"", result); @@ -55,7 +55,7 @@ mod tests { #[test] fn should_transpile_identifier() { let s = String::from("newValue"); - let exp = Expression::Identifier(&s); + let exp = Expression::Identifier(Box::new(s)); let result = exp.transpile(); assert_eq!("newValue", result); diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 77159c4..66da241 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -17,7 +17,7 @@ pub fn codegen<'a>(ast: &'a ModuleAST) -> String { #[cfg(test)] mod tests { - use crate::{lexic, semantic, symbol_table::SymbolTable, syntax}; + use crate::{lexic, syntax}; use super::*; @@ -26,8 +26,6 @@ mod tests { let input = String::from("val id = 322"); let tokens = lexic::get_tokens(&input).unwrap(); let mut ast = syntax::construct_ast(&tokens).unwrap(); - let mut table = SymbolTable::new(); - semantic::check_ast(&mut ast, &mut table); let out_str = codegen(&ast); diff --git a/src/codegen/module_ast.rs b/src/codegen/module_ast.rs index fa06f0d..6e2afd7 100644 --- a/src/codegen/module_ast.rs +++ b/src/codegen/module_ast.rs @@ -1,7 +1,7 @@ use super::Transpilable; use crate::ast_types::ModuleAST; -impl Transpilable for ModuleAST<'_> { +impl Transpilable for ModuleAST { /// Transpiles the whole AST into JS, using this same trait on the /// nodes and leaves of the AST fn transpile(&self) -> String { @@ -26,8 +26,8 @@ mod tests { let value = String::from("322"); let binding = Binding::Val(ValBinding { datatype: None, - identifier: &id, - expression: Expression::Number(&value), + identifier: Box::new(id), + expression: Expression::Number(Box::new(value)), }); let module = ModuleAST { diff --git a/src/file/mod.rs b/src/file/mod.rs index 2944a7e..5c7cd31 100644 --- a/src/file/mod.rs +++ b/src/file/mod.rs @@ -1,16 +1,6 @@ -use std::{ - fs, - path::{Path, PathBuf}, -}; +use std::{fs, path::Path}; -use crate::{ - codegen, - error_handling::PrintableError, - lexic, semantic, - symbol_table::{self, SymbolTable}, - syntax, - token::Token, -}; +use crate::{codegen, error_handling::PrintableError, lexic, syntax, token::Token}; pub fn compile_file(input: &String, output: &String) { let input_path = Path::new(input); @@ -48,12 +38,7 @@ fn build_ast(input: &String, tokens: Vec) -> String { let ast = syntax::construct_ast(&tokens); match ast { - Ok(ast) => { - let mut symbol_table = SymbolTable::new(); - semantic::check_ast(&ast, &mut symbol_table); - - codegen::codegen(&ast) - } + Ok(ast) => codegen::codegen(&ast), Err(reason) => { let chars: Vec = input.chars().into_iter().collect(); panic!("{}", reason.get_error_str(&chars)) diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index afe2c7b..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Module to handle the repl and its compilation -mod repl; -// Defines the types of tokens and provides functions to create them -mod token; -// Module to handle lexical analysis -mod syntax; -// Module to handle syntactic analysis -mod lexic; -// Module to handle semantic analysis -mod semantic; -// Defines the AST -mod ast_types; -// Defines the Symbol table and operations within -mod symbol_table; -// Transforms an AST to JS -mod codegen; -mod utils; - -mod error_handling; - -use error_handling::MistiError; -use token::Token; - -pub use token::TokenType; - -pub fn tokenize(input: &String) -> Result, MistiError> { - lexic::get_tokens(input) -} - -pub fn repl() { - let _ = repl::run(); -} diff --git a/src/main.rs b/src/main.rs index ad0fc95..7f631ed 100755 --- a/src/main.rs +++ b/src/main.rs @@ -10,12 +10,8 @@ mod token; mod syntax; // Module to handle syntactic analysis mod lexic; -// Module to handle semantic analysis -mod semantic; // Defines the AST mod ast_types; -// Defines the Symbol table and operations within -mod symbol_table; // Transforms an AST to JS mod codegen; mod utils; @@ -47,7 +43,7 @@ const VERSION: &str = "0.0.5"; fn get_copyright() -> String { format!( - "Misti {}\nCopyright (c) 2023 Fernando Enrique Araoz Morales\n", + "THP {}\nCopyright (c) 2023 Fernando Enrique Araoz Morales\n", VERSION, ) } @@ -62,9 +58,10 @@ fn main() { let cli = Cli::parse(); match &cli.command { - Some(Commands::C { file: input, output }) => { - file::compile_file(input, output) - } + Some(Commands::C { + file: input, + output, + }) => file::compile_file(input, output), Some(Commands::R {}) => { println!("{}", get_copyright()); let _ = repl::run(); diff --git a/src/repl/mod.rs b/src/repl/mod.rs index 51302f1..0de328a 100755 --- a/src/repl/mod.rs +++ b/src/repl/mod.rs @@ -1,21 +1,19 @@ use std::io::{self, Write}; use crate::error_handling::PrintableError; -use crate::symbol_table::SymbolTable; use crate::token::Token; use super::codegen; use super::lexic; -use super::semantic; use super::syntax; /// Executes Lexical analysis, handles errors and calls build_ast for the next phase -fn compile(input: &String, symbol_table: &mut SymbolTable) { +fn compile(input: &String) { let tokens = lexic::get_tokens(input); match tokens { Ok(tokens) => { - build_ast(input, tokens, symbol_table); + build_ast(input, tokens); } Err(error) => { let chars: Vec = input.chars().into_iter().collect(); @@ -27,13 +25,11 @@ fn compile(input: &String, symbol_table: &mut SymbolTable) { /// Executes Syntax analysis, and for now, Semantic analysis and Code generation. /// /// Prints the generated code in stdin -fn build_ast(input: &String, tokens: Vec, symbol_table: &mut SymbolTable) { +fn build_ast(input: &String, tokens: Vec) { let ast = syntax::construct_ast(&tokens); match ast { Ok(ast) => { - semantic::check_ast(&ast, symbol_table); - let js_code = codegen::codegen(&ast); println!("{}", js_code) } @@ -48,7 +44,6 @@ fn build_ast(input: &String, tokens: Vec, symbol_table: &mut SymbolTable) pub fn run() -> io::Result<()> { let stdin = io::stdin(); let mut buffer = String::new(); - let mut repl_symbol_table = SymbolTable::new(); println!("REPL: Enter expressions to evaluate. Type Ctrl-D to exit."); loop { @@ -63,7 +58,7 @@ pub fn run() -> io::Result<()> { break Ok(()); } Ok(_) => { - compile(&buffer, &mut repl_symbol_table); + compile(&buffer); } Err(error) => { eprintln!("Error reading stdin."); diff --git a/src/symbol_table.rs b/src/symbol_table.rs deleted file mode 100644 index 2c9b9bb..0000000 --- a/src/symbol_table.rs +++ /dev/null @@ -1,72 +0,0 @@ -use std::collections::HashMap; - -use crate::semantic::Datatype; - -pub struct SymbolTable { - /// For now just stores identifiers and datatypes - table: HashMap, -} - -impl SymbolTable { - pub fn new() -> SymbolTable { - let symbol_table = HashMap::::new(); - - SymbolTable { - table: symbol_table, - } - } - - pub fn insert(&mut self, identifier: &str, datatype: Datatype) { - self.table.insert(String::from(identifier), datatype); - } - - pub fn has_id(&self, identifier: &String) -> bool { - return self.table.contains_key::(identifier); - } - - pub fn check_type(&self, identifier: &String, datatype: Datatype) -> bool { - self.table - .get(identifier) - .and_then(|value| { - if *value == datatype { - Some(true) - } else { - Some(false) - } - }) - .unwrap_or(false) - } - - /// Returns the Datatype of a given identifier - pub fn get_type(&self, identifier: &String) -> Option<&Datatype> { - self.table.get(identifier).and_then(|value| Some(value)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn should_create() { - let mut _table = SymbolTable::new(); - } - - #[test] - fn should_add_identifier() { - let mut table = SymbolTable::new(); - table.insert("identifier", Datatype::num()); - - let s = String::from("identifier"); - assert_eq!(true, table.has_id(&s)) - } - - #[test] - fn should_check_type() { - let mut table = SymbolTable::new(); - table.insert("firstNumber", Datatype::num()); - - let s = String::from("firstNumber"); - assert!(table.check_type(&s, Datatype::num())); - } -} diff --git a/src/syntax/binding.rs b/src/syntax/binding.rs index 2eec9ab..c878ffa 100644 --- a/src/syntax/binding.rs +++ b/src/syntax/binding.rs @@ -109,13 +109,13 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> Option let binding = if is_val { Binding::Val(ValBinding { datatype: datatype_annotation, - identifier: &identifier.value, + identifier: Box::new(identifier.value.clone()), expression, }) } else { Binding::Var(VarBinding { datatype: datatype_annotation, - identifier: &identifier.value, + identifier: Box::new(identifier.value.clone()), expression, }) }; @@ -158,7 +158,7 @@ mod tests { match binding { SyntaxResult::Ok(Binding::Val(binding)) => { - assert_eq!("identifier", binding.identifier); + assert_eq!("identifier", format!("{}", binding.identifier)); } _ => panic!(), } @@ -197,7 +197,7 @@ mod tests { match binding { SyntaxResult::Ok(Binding::Val(binding)) => { assert_eq!(Some(String::from("Num")), binding.datatype); - assert_eq!("identifier", binding.identifier); + assert_eq!("identifier", format!("{}", binding.identifier)); } _ => panic!(), } @@ -208,7 +208,7 @@ mod tests { match binding { SyntaxResult::Ok(Binding::Var(binding)) => { assert_eq!(Some(String::from("Bool")), binding.datatype); - assert_eq!("identifier", binding.identifier); + assert_eq!("identifier", format!("{}", binding.identifier)); } _ => panic!(), } diff --git a/src/syntax/expression.rs b/src/syntax/expression.rs index d124a4d..2a336c1 100644 --- a/src/syntax/expression.rs +++ b/src/syntax/expression.rs @@ -9,12 +9,12 @@ use crate::token::{Token, TokenType}; /// - An identifier pub fn try_parse(tokens: &Vec, pos: usize) -> Option { tokens.get(pos).and_then(|token| match token.token_type { - TokenType::Number => Some(Expression::Number(&token.value)), - TokenType::String => Some(Expression::String(&token.value)), + TokenType::Number => Some(Expression::Number(Box::new(token.value.clone()))), + TokenType::String => Some(Expression::String(Box::new(token.value.clone()))), TokenType::Identifier if token.value == "true" || token.value == "false" => { Some(Expression::Boolean(token.value == "true")) } - TokenType::Identifier => Some(Expression::Identifier(&token.value)), + TokenType::Identifier => Some(Expression::Identifier(Box::new(token.value.clone()))), _ => None, }) } @@ -30,7 +30,7 @@ mod tests { let expression = try_parse(&tokens, 0).unwrap(); match expression { - Expression::Number(value) => assert_eq!("40", value), + Expression::Number(value) => assert_eq!("40", format!("{}", value)), _ => panic!(), } } @@ -41,7 +41,7 @@ mod tests { let expression = try_parse(&tokens, 0).unwrap(); match expression { - Expression::String(value) => assert_eq!("\"Hello\"", value), + Expression::String(value) => assert_eq!("\"Hello\"", format!("{}", value)), _ => panic!(), } } @@ -63,7 +63,7 @@ mod tests { let expression = try_parse(&tokens, 0).unwrap(); match expression { - Expression::Identifier(value) => assert_eq!("someIdentifier", value), + Expression::Identifier(value) => assert_eq!("someIdentifier", format!("{}", value)), _ => panic!(), } } diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index ab114a1..b9c4fa3 100755 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -9,10 +9,10 @@ use super::ast_types; use ast_types::ModuleAST; -pub enum SyntaxResult<'a> { +pub enum SyntaxResult { /// /// A construct has been found - Ok(Binding<'a>), + Ok(Binding), /// /// No construct was found None, @@ -22,7 +22,7 @@ pub enum SyntaxResult<'a> { } /// Constructs the Misti AST from a vector of tokens -pub fn construct_ast<'a>(tokens: &'a Vec) -> Result, MistiError> { +pub fn construct_ast<'a>(tokens: &'a Vec) -> Result { let _token_amount = tokens.len(); let mut current_pos = 0;