Remove lifetimes
This commit is contained in:
parent
4f1fc93ceb
commit
fe8f4f3fd1
16
Cargo.lock
generated
16
Cargo.lock
generated
@ -158,14 +158,6 @@ version = "0.1.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "misti"
|
|
||||||
version = "0.0.5"
|
|
||||||
dependencies = [
|
|
||||||
"clap",
|
|
||||||
"colored",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
@ -260,6 +252,14 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thp"
|
||||||
|
version = "0.0.5"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"colored",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "misti"
|
name = "thp"
|
||||||
version = "0.0.5"
|
version = "0.0.5"
|
||||||
edition = "2021"
|
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
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
pub struct ModuleAST<'a> {
|
pub struct ModuleAST {
|
||||||
pub bindings: Vec<Binding<'a>>,
|
pub bindings: Vec<Binding>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Binding<'a> {
|
pub enum Binding {
|
||||||
Val(ValBinding<'a>),
|
Val(ValBinding),
|
||||||
Var(VarBinding<'a>),
|
Var(VarBinding),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ValBinding<'a> {
|
pub struct ValBinding {
|
||||||
pub datatype: Option<String>,
|
pub datatype: Option<String>,
|
||||||
pub identifier: &'a String,
|
pub identifier: Box<String>,
|
||||||
pub expression: Expression<'a>,
|
pub expression: Expression,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VarBinding<'a> {
|
pub struct VarBinding {
|
||||||
pub datatype: Option<String>,
|
pub datatype: Option<String>,
|
||||||
pub identifier: &'a String,
|
pub identifier: Box<String>,
|
||||||
pub expression: Expression<'a>,
|
pub expression: Expression,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Expression<'a> {
|
pub enum Expression {
|
||||||
Number(&'a String),
|
Number(Box<String>),
|
||||||
String(&'a String),
|
String(Box<String>),
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Identifier(&'a String),
|
Identifier(Box<String>),
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::Transpilable;
|
use super::Transpilable;
|
||||||
use crate::ast_types::Binding;
|
use crate::ast_types::Binding;
|
||||||
|
|
||||||
impl Transpilable for Binding<'_> {
|
impl Transpilable for Binding {
|
||||||
/// Transpiles val and var bindings into JS.
|
/// Transpiles val and var bindings into JS.
|
||||||
fn transpile(&self) -> String {
|
fn transpile(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
@ -30,8 +30,8 @@ mod tests {
|
|||||||
let value = String::from("322");
|
let value = String::from("322");
|
||||||
let binding = Binding::Val(ValBinding {
|
let binding = Binding::Val(ValBinding {
|
||||||
datatype: None,
|
datatype: None,
|
||||||
identifier: &id,
|
identifier: Box::new(id),
|
||||||
expression: Expression::Number(&value),
|
expression: Expression::Number(Box::new(value)),
|
||||||
});
|
});
|
||||||
|
|
||||||
let result = binding.transpile();
|
let result = binding.transpile();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::Transpilable;
|
use super::Transpilable;
|
||||||
use crate::ast_types::Expression;
|
use crate::ast_types::Expression;
|
||||||
|
|
||||||
impl Transpilable for Expression<'_> {
|
impl Transpilable for Expression {
|
||||||
/// Transpiles an Expression to JS
|
/// Transpiles an Expression to JS
|
||||||
///
|
///
|
||||||
/// Right now the expressions in the grammar are:
|
/// Right now the expressions in the grammar are:
|
||||||
@ -11,12 +11,12 @@ impl Transpilable for Expression<'_> {
|
|||||||
/// - Identifier
|
/// - Identifier
|
||||||
fn transpile(&self) -> String {
|
fn transpile(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Expression::Number(value) => String::from(*value),
|
Expression::Number(value) => format!("{}", value),
|
||||||
Expression::String(value) => {
|
Expression::String(value) => {
|
||||||
format!("\"{}\"", *value)
|
format!("\"{}\"", *value)
|
||||||
}
|
}
|
||||||
Expression::Boolean(value) => String::from(if *value { "true" } else { "false" }),
|
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]
|
#[test]
|
||||||
fn should_transpile_number() {
|
fn should_transpile_number() {
|
||||||
let str = String::from("42");
|
let str = String::from("42");
|
||||||
let exp = Expression::Number(&str);
|
let exp = Expression::Number(Box::new(str));
|
||||||
let result = exp.transpile();
|
let result = exp.transpile();
|
||||||
|
|
||||||
assert_eq!("42", result);
|
assert_eq!("42", result);
|
||||||
@ -38,7 +38,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_transpile_string() {
|
fn should_transpile_string() {
|
||||||
let str = String::from("Hello world");
|
let str = String::from("Hello world");
|
||||||
let exp = Expression::String(&str);
|
let exp = Expression::String(Box::new(str));
|
||||||
let result = exp.transpile();
|
let result = exp.transpile();
|
||||||
|
|
||||||
assert_eq!("\"Hello world\"", result);
|
assert_eq!("\"Hello world\"", result);
|
||||||
@ -55,7 +55,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_transpile_identifier() {
|
fn should_transpile_identifier() {
|
||||||
let s = String::from("newValue");
|
let s = String::from("newValue");
|
||||||
let exp = Expression::Identifier(&s);
|
let exp = Expression::Identifier(Box::new(s));
|
||||||
let result = exp.transpile();
|
let result = exp.transpile();
|
||||||
|
|
||||||
assert_eq!("newValue", result);
|
assert_eq!("newValue", result);
|
||||||
|
@ -17,7 +17,7 @@ pub fn codegen<'a>(ast: &'a ModuleAST) -> String {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{lexic, semantic, symbol_table::SymbolTable, syntax};
|
use crate::{lexic, syntax};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -26,8 +26,6 @@ mod tests {
|
|||||||
let input = String::from("val id = 322");
|
let input = String::from("val id = 322");
|
||||||
let tokens = lexic::get_tokens(&input).unwrap();
|
let tokens = lexic::get_tokens(&input).unwrap();
|
||||||
let mut ast = syntax::construct_ast(&tokens).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);
|
let out_str = codegen(&ast);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::Transpilable;
|
use super::Transpilable;
|
||||||
use crate::ast_types::ModuleAST;
|
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
|
/// Transpiles the whole AST into JS, using this same trait on the
|
||||||
/// nodes and leaves of the AST
|
/// nodes and leaves of the AST
|
||||||
fn transpile(&self) -> String {
|
fn transpile(&self) -> String {
|
||||||
@ -26,8 +26,8 @@ mod tests {
|
|||||||
let value = String::from("322");
|
let value = String::from("322");
|
||||||
let binding = Binding::Val(ValBinding {
|
let binding = Binding::Val(ValBinding {
|
||||||
datatype: None,
|
datatype: None,
|
||||||
identifier: &id,
|
identifier: Box::new(id),
|
||||||
expression: Expression::Number(&value),
|
expression: Expression::Number(Box::new(value)),
|
||||||
});
|
});
|
||||||
|
|
||||||
let module = ModuleAST {
|
let module = ModuleAST {
|
||||||
|
@ -1,16 +1,6 @@
|
|||||||
use std::{
|
use std::{fs, path::Path};
|
||||||
fs,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{codegen, error_handling::PrintableError, lexic, syntax, token::Token};
|
||||||
codegen,
|
|
||||||
error_handling::PrintableError,
|
|
||||||
lexic, semantic,
|
|
||||||
symbol_table::{self, SymbolTable},
|
|
||||||
syntax,
|
|
||||||
token::Token,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn compile_file(input: &String, output: &String) {
|
pub fn compile_file(input: &String, output: &String) {
|
||||||
let input_path = Path::new(input);
|
let input_path = Path::new(input);
|
||||||
@ -48,12 +38,7 @@ fn build_ast(input: &String, tokens: Vec<Token>) -> String {
|
|||||||
let ast = syntax::construct_ast(&tokens);
|
let ast = syntax::construct_ast(&tokens);
|
||||||
|
|
||||||
match ast {
|
match ast {
|
||||||
Ok(ast) => {
|
Ok(ast) => codegen::codegen(&ast),
|
||||||
let mut symbol_table = SymbolTable::new();
|
|
||||||
semantic::check_ast(&ast, &mut symbol_table);
|
|
||||||
|
|
||||||
codegen::codegen(&ast)
|
|
||||||
}
|
|
||||||
Err(reason) => {
|
Err(reason) => {
|
||||||
let chars: Vec<char> = input.chars().into_iter().collect();
|
let chars: Vec<char> = input.chars().into_iter().collect();
|
||||||
panic!("{}", reason.get_error_str(&chars))
|
panic!("{}", reason.get_error_str(&chars))
|
||||||
|
32
src/lib.rs
32
src/lib.rs
@ -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<Vec<Token>, MistiError> {
|
|
||||||
lexic::get_tokens(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn repl() {
|
|
||||||
let _ = repl::run();
|
|
||||||
}
|
|
13
src/main.rs
13
src/main.rs
@ -10,12 +10,8 @@ mod token;
|
|||||||
mod syntax;
|
mod syntax;
|
||||||
// Module to handle syntactic analysis
|
// Module to handle syntactic analysis
|
||||||
mod lexic;
|
mod lexic;
|
||||||
// Module to handle semantic analysis
|
|
||||||
mod semantic;
|
|
||||||
// Defines the AST
|
// Defines the AST
|
||||||
mod ast_types;
|
mod ast_types;
|
||||||
// Defines the Symbol table and operations within
|
|
||||||
mod symbol_table;
|
|
||||||
// Transforms an AST to JS
|
// Transforms an AST to JS
|
||||||
mod codegen;
|
mod codegen;
|
||||||
mod utils;
|
mod utils;
|
||||||
@ -47,7 +43,7 @@ const VERSION: &str = "0.0.5";
|
|||||||
|
|
||||||
fn get_copyright() -> String {
|
fn get_copyright() -> String {
|
||||||
format!(
|
format!(
|
||||||
"Misti {}\nCopyright (c) 2023 Fernando Enrique Araoz Morales\n",
|
"THP {}\nCopyright (c) 2023 Fernando Enrique Araoz Morales\n",
|
||||||
VERSION,
|
VERSION,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -62,9 +58,10 @@ fn main() {
|
|||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
match &cli.command {
|
match &cli.command {
|
||||||
Some(Commands::C { file: input, output }) => {
|
Some(Commands::C {
|
||||||
file::compile_file(input, output)
|
file: input,
|
||||||
}
|
output,
|
||||||
|
}) => file::compile_file(input, output),
|
||||||
Some(Commands::R {}) => {
|
Some(Commands::R {}) => {
|
||||||
println!("{}", get_copyright());
|
println!("{}", get_copyright());
|
||||||
let _ = repl::run();
|
let _ = repl::run();
|
||||||
|
@ -1,21 +1,19 @@
|
|||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
use crate::error_handling::PrintableError;
|
use crate::error_handling::PrintableError;
|
||||||
use crate::symbol_table::SymbolTable;
|
|
||||||
use crate::token::Token;
|
use crate::token::Token;
|
||||||
|
|
||||||
use super::codegen;
|
use super::codegen;
|
||||||
use super::lexic;
|
use super::lexic;
|
||||||
use super::semantic;
|
|
||||||
use super::syntax;
|
use super::syntax;
|
||||||
|
|
||||||
/// Executes Lexical analysis, handles errors and calls build_ast for the next phase
|
/// 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);
|
let tokens = lexic::get_tokens(input);
|
||||||
|
|
||||||
match tokens {
|
match tokens {
|
||||||
Ok(tokens) => {
|
Ok(tokens) => {
|
||||||
build_ast(input, tokens, symbol_table);
|
build_ast(input, tokens);
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let chars: Vec<char> = input.chars().into_iter().collect();
|
let chars: Vec<char> = 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.
|
/// Executes Syntax analysis, and for now, Semantic analysis and Code generation.
|
||||||
///
|
///
|
||||||
/// Prints the generated code in stdin
|
/// Prints the generated code in stdin
|
||||||
fn build_ast(input: &String, tokens: Vec<Token>, symbol_table: &mut SymbolTable) {
|
fn build_ast(input: &String, tokens: Vec<Token>) {
|
||||||
let ast = syntax::construct_ast(&tokens);
|
let ast = syntax::construct_ast(&tokens);
|
||||||
|
|
||||||
match ast {
|
match ast {
|
||||||
Ok(ast) => {
|
Ok(ast) => {
|
||||||
semantic::check_ast(&ast, symbol_table);
|
|
||||||
|
|
||||||
let js_code = codegen::codegen(&ast);
|
let js_code = codegen::codegen(&ast);
|
||||||
println!("{}", js_code)
|
println!("{}", js_code)
|
||||||
}
|
}
|
||||||
@ -48,7 +44,6 @@ fn build_ast(input: &String, tokens: Vec<Token>, symbol_table: &mut SymbolTable)
|
|||||||
pub fn run() -> io::Result<()> {
|
pub fn run() -> io::Result<()> {
|
||||||
let stdin = io::stdin();
|
let stdin = io::stdin();
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
let mut repl_symbol_table = SymbolTable::new();
|
|
||||||
|
|
||||||
println!("REPL: Enter expressions to evaluate. Type Ctrl-D to exit.");
|
println!("REPL: Enter expressions to evaluate. Type Ctrl-D to exit.");
|
||||||
loop {
|
loop {
|
||||||
@ -63,7 +58,7 @@ pub fn run() -> io::Result<()> {
|
|||||||
break Ok(());
|
break Ok(());
|
||||||
}
|
}
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
compile(&buffer, &mut repl_symbol_table);
|
compile(&buffer);
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
eprintln!("Error reading stdin.");
|
eprintln!("Error reading stdin.");
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use crate::semantic::Datatype;
|
|
||||||
|
|
||||||
pub struct SymbolTable {
|
|
||||||
/// For now just stores identifiers and datatypes
|
|
||||||
table: HashMap<String, Datatype>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolTable {
|
|
||||||
pub fn new() -> SymbolTable {
|
|
||||||
let symbol_table = HashMap::<String, Datatype>::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::<String>(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()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -109,13 +109,13 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> Option<SyntaxResult>
|
|||||||
let binding = if is_val {
|
let binding = if is_val {
|
||||||
Binding::Val(ValBinding {
|
Binding::Val(ValBinding {
|
||||||
datatype: datatype_annotation,
|
datatype: datatype_annotation,
|
||||||
identifier: &identifier.value,
|
identifier: Box::new(identifier.value.clone()),
|
||||||
expression,
|
expression,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Binding::Var(VarBinding {
|
Binding::Var(VarBinding {
|
||||||
datatype: datatype_annotation,
|
datatype: datatype_annotation,
|
||||||
identifier: &identifier.value,
|
identifier: Box::new(identifier.value.clone()),
|
||||||
expression,
|
expression,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -158,7 +158,7 @@ mod tests {
|
|||||||
|
|
||||||
match binding {
|
match binding {
|
||||||
SyntaxResult::Ok(Binding::Val(binding)) => {
|
SyntaxResult::Ok(Binding::Val(binding)) => {
|
||||||
assert_eq!("identifier", binding.identifier);
|
assert_eq!("identifier", format!("{}", binding.identifier));
|
||||||
}
|
}
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
@ -197,7 +197,7 @@ mod tests {
|
|||||||
match binding {
|
match binding {
|
||||||
SyntaxResult::Ok(Binding::Val(binding)) => {
|
SyntaxResult::Ok(Binding::Val(binding)) => {
|
||||||
assert_eq!(Some(String::from("Num")), binding.datatype);
|
assert_eq!(Some(String::from("Num")), binding.datatype);
|
||||||
assert_eq!("identifier", binding.identifier);
|
assert_eq!("identifier", format!("{}", binding.identifier));
|
||||||
}
|
}
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
@ -208,7 +208,7 @@ mod tests {
|
|||||||
match binding {
|
match binding {
|
||||||
SyntaxResult::Ok(Binding::Var(binding)) => {
|
SyntaxResult::Ok(Binding::Var(binding)) => {
|
||||||
assert_eq!(Some(String::from("Bool")), binding.datatype);
|
assert_eq!(Some(String::from("Bool")), binding.datatype);
|
||||||
assert_eq!("identifier", binding.identifier);
|
assert_eq!("identifier", format!("{}", binding.identifier));
|
||||||
}
|
}
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,12 @@ use crate::token::{Token, TokenType};
|
|||||||
/// - An identifier
|
/// - An identifier
|
||||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> Option<Expression> {
|
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> Option<Expression> {
|
||||||
tokens.get(pos).and_then(|token| match token.token_type {
|
tokens.get(pos).and_then(|token| match token.token_type {
|
||||||
TokenType::Number => Some(Expression::Number(&token.value)),
|
TokenType::Number => Some(Expression::Number(Box::new(token.value.clone()))),
|
||||||
TokenType::String => Some(Expression::String(&token.value)),
|
TokenType::String => Some(Expression::String(Box::new(token.value.clone()))),
|
||||||
TokenType::Identifier if token.value == "true" || token.value == "false" => {
|
TokenType::Identifier if token.value == "true" || token.value == "false" => {
|
||||||
Some(Expression::Boolean(token.value == "true"))
|
Some(Expression::Boolean(token.value == "true"))
|
||||||
}
|
}
|
||||||
TokenType::Identifier => Some(Expression::Identifier(&token.value)),
|
TokenType::Identifier => Some(Expression::Identifier(Box::new(token.value.clone()))),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ mod tests {
|
|||||||
let expression = try_parse(&tokens, 0).unwrap();
|
let expression = try_parse(&tokens, 0).unwrap();
|
||||||
|
|
||||||
match expression {
|
match expression {
|
||||||
Expression::Number(value) => assert_eq!("40", value),
|
Expression::Number(value) => assert_eq!("40", format!("{}", value)),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ mod tests {
|
|||||||
let expression = try_parse(&tokens, 0).unwrap();
|
let expression = try_parse(&tokens, 0).unwrap();
|
||||||
|
|
||||||
match expression {
|
match expression {
|
||||||
Expression::String(value) => assert_eq!("\"Hello\"", value),
|
Expression::String(value) => assert_eq!("\"Hello\"", format!("{}", value)),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ mod tests {
|
|||||||
let expression = try_parse(&tokens, 0).unwrap();
|
let expression = try_parse(&tokens, 0).unwrap();
|
||||||
|
|
||||||
match expression {
|
match expression {
|
||||||
Expression::Identifier(value) => assert_eq!("someIdentifier", value),
|
Expression::Identifier(value) => assert_eq!("someIdentifier", format!("{}", value)),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,10 @@ use super::ast_types;
|
|||||||
|
|
||||||
use ast_types::ModuleAST;
|
use ast_types::ModuleAST;
|
||||||
|
|
||||||
pub enum SyntaxResult<'a> {
|
pub enum SyntaxResult {
|
||||||
///
|
///
|
||||||
/// A construct has been found
|
/// A construct has been found
|
||||||
Ok(Binding<'a>),
|
Ok(Binding),
|
||||||
///
|
///
|
||||||
/// No construct was found
|
/// No construct was found
|
||||||
None,
|
None,
|
||||||
@ -22,7 +22,7 @@ pub enum SyntaxResult<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs the Misti AST from a vector of tokens
|
/// Constructs the Misti AST from a vector of tokens
|
||||||
pub fn construct_ast<'a>(tokens: &'a Vec<Token>) -> Result<ModuleAST<'a>, MistiError> {
|
pub fn construct_ast<'a>(tokens: &'a Vec<Token>) -> Result<ModuleAST, MistiError> {
|
||||||
let _token_amount = tokens.len();
|
let _token_amount = tokens.len();
|
||||||
let mut current_pos = 0;
|
let mut current_pos = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user