Add lifetimes
This commit is contained in:
parent
e074e2cd74
commit
ed9ccab5e1
@ -1,7 +1,7 @@
|
|||||||
use super::Transpilable;
|
use super::Transpilable;
|
||||||
use crate::syntax::ast::var_binding::Binding;
|
use crate::syntax::ast::var_binding::Binding;
|
||||||
|
|
||||||
impl Transpilable for Binding {
|
impl Transpilable for Binding<'_> {
|
||||||
/// Transpiles val and var bindings into PHP.
|
/// Transpiles val and var bindings into PHP.
|
||||||
fn transpile(&self) -> String {
|
fn transpile(&self) -> String {
|
||||||
let expression_str = self.expression.transpile();
|
let expression_str = self.expression.transpile();
|
||||||
@ -22,7 +22,7 @@ mod tests {
|
|||||||
let binding = Binding {
|
let binding = Binding {
|
||||||
datatype: None,
|
datatype: None,
|
||||||
identifier: Box::new(id),
|
identifier: Box::new(id),
|
||||||
expression: Expression::Number(Box::new(value)),
|
expression: Expression::Number(&value),
|
||||||
is_mutable: false,
|
is_mutable: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ use crate::syntax::ast::Block;
|
|||||||
|
|
||||||
use super::Transpilable;
|
use super::Transpilable;
|
||||||
|
|
||||||
impl Transpilable for Block {
|
impl Transpilable for Block<'_> {
|
||||||
fn transpile(&self) -> String {
|
fn transpile(&self) -> String {
|
||||||
// TODO: Handle indentation
|
// TODO: Handle indentation
|
||||||
self.statements
|
self.statements
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::Transpilable;
|
use super::Transpilable;
|
||||||
use crate::syntax::ast::Expression;
|
use crate::syntax::ast::Expression;
|
||||||
|
|
||||||
impl Transpilable for Expression {
|
impl Transpilable for Expression<'_> {
|
||||||
/// Transpiles an Expression to PHP
|
/// Transpiles an Expression to PHP
|
||||||
///
|
///
|
||||||
/// Right now the expressions in the grammar are:
|
/// Right now the expressions in the grammar are:
|
||||||
@ -41,7 +41,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(Box::new(str));
|
let exp = Expression::Number(&str);
|
||||||
let result = exp.transpile();
|
let result = exp.transpile();
|
||||||
|
|
||||||
assert_eq!("42", result);
|
assert_eq!("42", result);
|
||||||
@ -50,7 +50,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(Box::new(str));
|
let exp = Expression::String(&str);
|
||||||
let result = exp.transpile();
|
let result = exp.transpile();
|
||||||
|
|
||||||
assert_eq!("\"Hello world\"", result);
|
assert_eq!("\"Hello world\"", result);
|
||||||
@ -67,7 +67,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(Box::new(s));
|
let exp = Expression::Identifier(&s);
|
||||||
let result = exp.transpile();
|
let result = exp.transpile();
|
||||||
|
|
||||||
assert_eq!("newValue", result);
|
assert_eq!("newValue", result);
|
||||||
|
@ -2,7 +2,7 @@ use crate::syntax::ast::functions::FunctionCall;
|
|||||||
|
|
||||||
use super::Transpilable;
|
use super::Transpilable;
|
||||||
|
|
||||||
impl Transpilable for FunctionCall {
|
impl Transpilable for FunctionCall<'_> {
|
||||||
fn transpile(&self) -> String {
|
fn transpile(&self) -> String {
|
||||||
let parameters = &self
|
let parameters = &self
|
||||||
.arguments
|
.arguments
|
||||||
|
@ -27,7 +27,7 @@ mod tests {
|
|||||||
let binding = Binding {
|
let binding = Binding {
|
||||||
datatype: None,
|
datatype: None,
|
||||||
identifier: Box::new(id),
|
identifier: Box::new(id),
|
||||||
expression: Expression::Number(Box::new(value)),
|
expression: Expression::Number(&value),
|
||||||
is_mutable: false,
|
is_mutable: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ use crate::syntax::ast::statement::Statement;
|
|||||||
|
|
||||||
use super::Transpilable;
|
use super::Transpilable;
|
||||||
|
|
||||||
impl Transpilable for Statement {
|
impl Transpilable for Statement<'_> {
|
||||||
fn transpile(&self) -> String {
|
fn transpile(&self) -> String {
|
||||||
let stmt = match self {
|
let stmt = match self {
|
||||||
Statement::FunctionCall(f) => f.transpile(),
|
Statement::FunctionCall(f) => f.transpile(),
|
||||||
|
@ -40,7 +40,10 @@ impl SemanticCheck for TopLevelDeclaration<'_> {
|
|||||||
let error = SemanticError {
|
let error = SemanticError {
|
||||||
error_start: function.identifier.position,
|
error_start: function.identifier.position,
|
||||||
error_end: function.identifier.get_end_position(),
|
error_end: function.identifier.get_end_position(),
|
||||||
reason: format!("Duplicated function: A function with name {} was already defined", function_name),
|
reason: format!(
|
||||||
|
"Duplicated function: A function with name {} was already defined",
|
||||||
|
function_name
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
return Err(MistiError::Semantic(error));
|
return Err(MistiError::Semantic(error));
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use super::Expression;
|
use super::Expression;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FunctionCall {
|
pub struct FunctionCall<'a> {
|
||||||
pub function: Box<Expression>,
|
pub function: Box<Expression<'a>>,
|
||||||
pub arguments: Box<ArgumentsList>,
|
pub arguments: Box<ArgumentsList<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ArgumentsList {
|
pub struct ArgumentsList<'a> {
|
||||||
pub arguments: Vec<Expression>,
|
pub arguments: Vec<Expression<'a>>,
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ pub struct ModuleAST<'a> {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum TopLevelDeclaration<'a> {
|
pub enum TopLevelDeclaration<'a> {
|
||||||
Binding(var_binding::Binding),
|
Binding(var_binding::Binding<'a>),
|
||||||
FunctionDeclaration(FunctionDeclaration<'a>),
|
FunctionDeclaration(FunctionDeclaration<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,29 +20,29 @@ pub enum TopLevelDeclaration<'a> {
|
|||||||
pub struct FunctionDeclaration<'a> {
|
pub struct FunctionDeclaration<'a> {
|
||||||
pub identifier: &'a Token,
|
pub identifier: &'a Token,
|
||||||
pub params_list: Box<ParamsList>,
|
pub params_list: Box<ParamsList>,
|
||||||
pub block: Box<Block>,
|
pub block: Box<Block<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Block {
|
pub struct Block<'a> {
|
||||||
pub statements: Vec<statement::Statement>,
|
pub statements: Vec<statement::Statement<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ParamsList {}
|
pub struct ParamsList {}
|
||||||
|
|
||||||
pub struct Parameter {
|
pub struct Parameter<'a> {
|
||||||
pub identifier: Box<String>,
|
pub identifier: &'a String,
|
||||||
pub datatype: Box<String>,
|
pub datatype: &'a String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Expression {
|
pub enum Expression<'a> {
|
||||||
Number(Box<String>),
|
Number(&'a String),
|
||||||
String(Box<String>),
|
String(&'a String),
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Identifier(Box<String>),
|
Identifier(&'a String),
|
||||||
FunctionCall(FunctionCall),
|
FunctionCall(FunctionCall<'a>),
|
||||||
UnaryOperator(Box<String>, Box<Expression>),
|
UnaryOperator(&'a String, Box<Expression<'a>>),
|
||||||
BinaryOperator(Box<Expression>, Box<Expression>, Box<String>),
|
BinaryOperator(Box<Expression<'a>>, Box<Expression<'a>>, &'a String),
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::{functions::FunctionCall, var_binding::Binding};
|
use super::{functions::FunctionCall, var_binding::Binding};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Statement {
|
pub enum Statement<'a> {
|
||||||
FunctionCall(FunctionCall),
|
FunctionCall(FunctionCall<'a>),
|
||||||
Binding(Binding),
|
Binding(Binding<'a>),
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use super::Expression;
|
use super::Expression;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Binding {
|
pub struct Binding<'a> {
|
||||||
pub datatype: Option<String>,
|
pub datatype: Option<String>,
|
||||||
pub identifier: Box<String>,
|
pub identifier: Box<String>,
|
||||||
pub expression: Expression,
|
pub expression: Expression<'a>,
|
||||||
pub is_mutable: bool,
|
pub is_mutable: bool,
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,11 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()>
|
|||||||
parse_many(tokens, next_pos, term)
|
parse_many(tokens, next_pos, term)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_many(
|
fn parse_many<'a>(
|
||||||
tokens: &Vec<Token>,
|
tokens: &'a Vec<Token>,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
prev_expr: Expression,
|
prev_expr: Expression<'a>,
|
||||||
) -> ParseResult<Expression, ()> {
|
) -> ParseResult<Expression<'a>, ()> {
|
||||||
// comparison = term, ((">" | ">=" | "<" | "<="), term)*;
|
// comparison = term, ((">" | ">=" | "<" | "<="), term)*;
|
||||||
|
|
||||||
match tokens.get(pos) {
|
match tokens.get(pos) {
|
||||||
@ -36,7 +36,7 @@ fn parse_many(
|
|||||||
let expr = Expression::BinaryOperator(
|
let expr = Expression::BinaryOperator(
|
||||||
Box::new(prev_expr),
|
Box::new(prev_expr),
|
||||||
Box::new(expr),
|
Box::new(expr),
|
||||||
Box::new(token.value.clone()),
|
&token.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
parse_many(tokens, next_pos, expr)
|
parse_many(tokens, next_pos, expr)
|
||||||
|
@ -17,11 +17,11 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()>
|
|||||||
parse_many(tokens, next_pos, comparison)
|
parse_many(tokens, next_pos, comparison)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_many(
|
fn parse_many<'a>(
|
||||||
tokens: &Vec<Token>,
|
tokens: &'a Vec<Token>,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
prev_expr: Expression,
|
prev_expr: Expression<'a>,
|
||||||
) -> ParseResult<Expression, ()> {
|
) -> ParseResult<Expression<'a>, ()> {
|
||||||
// equality = comparison, (("==" | "!="), comparison )*;
|
// equality = comparison, (("==" | "!="), comparison )*;
|
||||||
|
|
||||||
match tokens.get(pos) {
|
match tokens.get(pos) {
|
||||||
@ -31,7 +31,7 @@ fn parse_many(
|
|||||||
let expr = Expression::BinaryOperator(
|
let expr = Expression::BinaryOperator(
|
||||||
Box::new(prev_expr),
|
Box::new(prev_expr),
|
||||||
Box::new(expr),
|
Box::new(expr),
|
||||||
Box::new(token.value.clone()),
|
&token.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
parse_many(tokens, next_pos, expr)
|
parse_many(tokens, next_pos, expr)
|
||||||
|
@ -17,11 +17,11 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()>
|
|||||||
parse_many(tokens, next_pos, unary)
|
parse_many(tokens, next_pos, unary)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_many(
|
fn parse_many<'a>(
|
||||||
tokens: &Vec<Token>,
|
tokens: &'a Vec<Token>,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
prev_expr: Expression,
|
prev_expr: Expression<'a>,
|
||||||
) -> ParseResult<Expression, ()> {
|
) -> ParseResult<Expression<'a>, ()> {
|
||||||
// (("/" | "*"), unary)*
|
// (("/" | "*"), unary)*
|
||||||
|
|
||||||
match tokens.get(pos) {
|
match tokens.get(pos) {
|
||||||
@ -31,7 +31,7 @@ fn parse_many(
|
|||||||
let expr = Expression::BinaryOperator(
|
let expr = Expression::BinaryOperator(
|
||||||
Box::new(prev_expr),
|
Box::new(prev_expr),
|
||||||
Box::new(expr),
|
Box::new(expr),
|
||||||
Box::new(token.value.clone()),
|
&token.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
parse_many(tokens, next_pos, expr)
|
parse_many(tokens, next_pos, expr)
|
||||||
|
@ -12,21 +12,14 @@ use crate::{
|
|||||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
|
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
|
||||||
match tokens.get_significant(pos) {
|
match tokens.get_significant(pos) {
|
||||||
Some((token, token_pos)) => match token.token_type {
|
Some((token, token_pos)) => match token.token_type {
|
||||||
TokenType::Number => ParseResult::Ok(
|
TokenType::Number => ParseResult::Ok(Expression::Number(&token.value), token_pos + 1),
|
||||||
Expression::Number(Box::new(token.value.clone())),
|
TokenType::String => ParseResult::Ok(Expression::String(&token.value), token_pos + 1),
|
||||||
token_pos + 1,
|
|
||||||
),
|
|
||||||
TokenType::String => ParseResult::Ok(
|
|
||||||
Expression::String(Box::new(token.value.clone())),
|
|
||||||
token_pos + 1,
|
|
||||||
),
|
|
||||||
TokenType::Identifier if token.value == "true" || token.value == "false" => {
|
TokenType::Identifier if token.value == "true" || token.value == "false" => {
|
||||||
ParseResult::Ok(Expression::Boolean(token.value == "true"), token_pos + 1)
|
ParseResult::Ok(Expression::Boolean(token.value == "true"), token_pos + 1)
|
||||||
}
|
}
|
||||||
TokenType::Identifier => ParseResult::Ok(
|
TokenType::Identifier => {
|
||||||
Expression::Identifier(Box::new(token.value.clone())),
|
ParseResult::Ok(Expression::Identifier(&token.value), token_pos + 1)
|
||||||
token_pos + 1,
|
}
|
||||||
),
|
|
||||||
TokenType::LeftParen => parse_parenthesized_expression(tokens, token_pos),
|
TokenType::LeftParen => parse_parenthesized_expression(tokens, token_pos),
|
||||||
_ => ParseResult::Unmatched,
|
_ => ParseResult::Unmatched,
|
||||||
},
|
},
|
||||||
|
@ -17,11 +17,11 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()>
|
|||||||
parse_many(tokens, next_pos, factor)
|
parse_many(tokens, next_pos, factor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_many(
|
fn parse_many<'a>(
|
||||||
tokens: &Vec<Token>,
|
tokens: &'a Vec<Token>,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
prev_expr: Expression,
|
prev_expr: Expression<'a>,
|
||||||
) -> ParseResult<Expression, ()> {
|
) -> ParseResult<Expression<'a>, ()> {
|
||||||
// term = factor, (("-" | "+"), factor)*;
|
// term = factor, (("-" | "+"), factor)*;
|
||||||
|
|
||||||
match tokens.get(pos) {
|
match tokens.get(pos) {
|
||||||
@ -31,7 +31,7 @@ fn parse_many(
|
|||||||
let expr = Expression::BinaryOperator(
|
let expr = Expression::BinaryOperator(
|
||||||
Box::new(prev_expr),
|
Box::new(prev_expr),
|
||||||
Box::new(expr),
|
Box::new(expr),
|
||||||
Box::new(token.value.clone()),
|
&token.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
parse_many(tokens, next_pos, expr)
|
parse_many(tokens, next_pos, expr)
|
||||||
|
@ -16,7 +16,7 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()>
|
|||||||
Some(token) if token.value == "!" || token.value == "-" => {
|
Some(token) if token.value == "!" || token.value == "-" => {
|
||||||
match super::try_parse(tokens, pos + 1) {
|
match super::try_parse(tokens, pos + 1) {
|
||||||
ParseResult::Ok(expression, next_pos) => ParseResult::Ok(
|
ParseResult::Ok(expression, next_pos) => ParseResult::Ok(
|
||||||
Expression::UnaryOperator(Box::new(token.value.clone()), Box::new(expression)),
|
Expression::UnaryOperator(&token.value, Box::new(expression)),
|
||||||
next_pos,
|
next_pos,
|
||||||
),
|
),
|
||||||
_ => ParseResult::Unmatched,
|
_ => ParseResult::Unmatched,
|
||||||
|
@ -129,8 +129,8 @@ fn parse_param_definition<'a>(
|
|||||||
|
|
||||||
ParseResult::Ok(
|
ParseResult::Ok(
|
||||||
Parameter {
|
Parameter {
|
||||||
identifier: Box::new(identifier.value.clone()),
|
identifier: &identifier.value,
|
||||||
datatype: Box::new(datatype.value.clone()),
|
datatype: &datatype.value,
|
||||||
},
|
},
|
||||||
next_pos,
|
next_pos,
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user