refactor: change tokenize api
This commit is contained in:
parent
4ac01099ce
commit
912384c856
@ -11,9 +11,9 @@ use std::io::{self, BufRead};
|
|||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
enum TokenizeResult {
|
enum TokenizeResult {
|
||||||
Ok(Vec<Token>),
|
Ok(Vec<Token>),
|
||||||
SyntaxOnly(Vec<Token>, MistiError),
|
SemanticError(Vec<Token>, MistiError),
|
||||||
TokensOnly(Vec<Token>, MistiError),
|
SyntaxError(Vec<Token>, MistiError),
|
||||||
Err(MistiError),
|
LexError(MistiError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tokenize_command(_options: Vec<String>) -> Result<(), ()> {
|
pub fn tokenize_command(_options: Vec<String>) -> Result<(), ()> {
|
||||||
@ -40,12 +40,12 @@ pub fn tokenize_command(_options: Vec<String>) -> Result<(), ()> {
|
|||||||
match ast_result {
|
match ast_result {
|
||||||
Ok(ast) => match semantic::check_semantics(&ast) {
|
Ok(ast) => match semantic::check_semantics(&ast) {
|
||||||
Ok(()) => TokenizeResult::Ok(tokens),
|
Ok(()) => TokenizeResult::Ok(tokens),
|
||||||
Err(error) => TokenizeResult::SyntaxOnly(tokens, error),
|
Err(error) => TokenizeResult::SemanticError(tokens, error),
|
||||||
},
|
},
|
||||||
Err(error) => TokenizeResult::TokensOnly(tokens, error),
|
Err(error) => TokenizeResult::SyntaxError(tokens, error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(error) => TokenizeResult::Err(error),
|
Err(error) => TokenizeResult::LexError(error),
|
||||||
};
|
};
|
||||||
|
|
||||||
let json = serde_json::to_string(&result).unwrap();
|
let json = serde_json::to_string(&result).unwrap();
|
||||||
|
@ -21,6 +21,7 @@ mod tests {
|
|||||||
php_ast::{PhpAssignmentExpression, PhpPrimaryExpression, PhpSimpleAssignment},
|
php_ast::{PhpAssignmentExpression, PhpPrimaryExpression, PhpSimpleAssignment},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn should_gen_assignment() {
|
fn should_gen_assignment() {
|
||||||
let variable = String::from("name");
|
let variable = String::from("name");
|
||||||
@ -35,4 +36,5 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!("$name = \"John\"", output)
|
assert_eq!("$name = \"John\"", output)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ mod tests {
|
|||||||
assert_eq!("<?php\n", output);
|
assert_eq!("<?php\n", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn should_transpile_expr_statement() {
|
fn should_transpile_expr_statement() {
|
||||||
let value = String::from("Hello world!");
|
let value = String::from("Hello world!");
|
||||||
@ -43,4 +44,5 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!("<?php\n\"Hello world!\";", output);
|
assert_eq!("<?php\n\"Hello world!\";", output);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use crate::codegen::Transpilable;
|
||||||
|
|
||||||
/// This AST implements a subset of the PHP AST as defined
|
/// This AST implements a subset of the PHP AST as defined
|
||||||
/// by https://phplang.org/spec/19-grammar.html#syntactic-grammar
|
/// by https://phplang.org/spec/19-grammar.html#syntactic-grammar
|
||||||
///
|
///
|
||||||
@ -5,10 +7,12 @@
|
|||||||
/// THP
|
/// THP
|
||||||
pub mod transformers;
|
pub mod transformers;
|
||||||
|
|
||||||
|
type TranspilableBox<'a> = Box<(dyn Transpilable + 'a)>;
|
||||||
|
|
||||||
/// Represents `statement-list` on the grammar,
|
/// Represents `statement-list` on the grammar,
|
||||||
/// and thus a whole PHP source file
|
/// and thus a whole PHP source file
|
||||||
pub struct PhpAst<'a> {
|
pub struct PhpAst<'a> {
|
||||||
pub statements: Vec<PhpStatement<'a>>,
|
pub statements: Vec<TranspilableBox<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://phplang.org/spec/19-grammar.html#grammar-statement
|
/// https://phplang.org/spec/19-grammar.html#grammar-statement
|
||||||
@ -37,7 +41,7 @@ pub enum PhpAssignmentExpression<'a> {
|
|||||||
|
|
||||||
pub struct PhpSimpleAssignment<'a> {
|
pub struct PhpSimpleAssignment<'a> {
|
||||||
pub variable: String,
|
pub variable: String,
|
||||||
pub assignment: PhpPrimaryExpression<'a>,
|
pub assignment: TranspilableBox<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://phplang.org/spec/19-grammar.html#grammar-primary-expression
|
/// https://phplang.org/spec/19-grammar.html#grammar-primary-expression
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
use super::super::PhpExpression;
|
use super::super::PhpExpression;
|
||||||
use crate::{
|
use crate::{
|
||||||
php_ast::{PhpAssignmentExpression, PhpPrimaryExpression},
|
codegen::Transpilable, php_ast::{PhpAssignmentExpression, PhpPrimaryExpression}, syntax::ast::Expression
|
||||||
syntax::ast::Expression,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: next rewrite the test to use the output of Transpilable?
|
||||||
|
|
||||||
use super::PHPTransformable;
|
use super::PHPTransformable;
|
||||||
|
|
||||||
/// Transforms a THP expression into a PHP expression
|
/// Transforms a THP expression into a PHP expression
|
||||||
impl<'a> PHPTransformable<'a> for Expression<'_> {
|
impl<'a> PHPTransformable<'a> for Expression<'_> {
|
||||||
type Item = PhpExpression<'a>;
|
fn into_php_ast(&'a self) -> Box<(dyn Transpilable + 'a)> {
|
||||||
|
|
||||||
fn into_php_ast(&'a self) -> Self::Item {
|
|
||||||
match self {
|
match self {
|
||||||
Expression::String(value) => {
|
Expression::String(value) => {
|
||||||
let expr = PhpPrimaryExpression::StringLiteral(&value.value);
|
let expr = PhpPrimaryExpression::StringLiteral(&value.value);
|
||||||
PhpExpression::Assignment(PhpAssignmentExpression::Primary(expr))
|
Box::new(PhpExpression::Assignment(PhpAssignmentExpression::Primary(expr)))
|
||||||
}
|
}
|
||||||
Expression::Int(value) => {
|
Expression::Int(value) => {
|
||||||
let expr = PhpPrimaryExpression::IntegerLiteral(&value.value);
|
let expr = PhpPrimaryExpression::IntegerLiteral(&value.value);
|
||||||
PhpExpression::Assignment(PhpAssignmentExpression::Primary(expr))
|
Box::new(PhpExpression::Assignment(PhpAssignmentExpression::Primary(expr)))
|
||||||
}
|
}
|
||||||
Expression::Float(value) => {
|
Expression::Float(value) => {
|
||||||
let expr = PhpPrimaryExpression::FloatingLiteral(&value.value);
|
let expr = PhpPrimaryExpression::FloatingLiteral(&value.value);
|
||||||
PhpExpression::Assignment(PhpAssignmentExpression::Primary(expr))
|
Box::new(PhpExpression::Assignment(PhpAssignmentExpression::Primary(expr)))
|
||||||
}
|
}
|
||||||
_ => todo!("transformation for expression: {:?}", self),
|
_ => todo!("transformation for expression: {:?}", self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -88,3 +88,4 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
use crate::codegen::Transpilable;
|
||||||
|
|
||||||
pub mod expression;
|
pub mod expression;
|
||||||
pub mod module_ast;
|
pub mod module_ast;
|
||||||
pub mod statement;
|
pub mod statement;
|
||||||
|
|
||||||
/// Implemented by AST nodes that can be transformed to PHP
|
/// Implemented by AST nodes that can be transformed to PHP
|
||||||
pub trait PHPTransformable<'a> {
|
pub trait PHPTransformable<'a> {
|
||||||
type Item;
|
fn into_php_ast(&'a self) -> Box<(dyn Transpilable + 'a)>;
|
||||||
|
|
||||||
fn into_php_ast(&'a self) -> Self::Item;
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::super::PhpAst;
|
use super::super::PhpAst;
|
||||||
|
use crate::codegen::Transpilable;
|
||||||
use crate::php_ast::{
|
use crate::php_ast::{
|
||||||
PhpAssignmentExpression, PhpExpression, PhpExpressionList, PhpPrimaryExpression, PhpStatement,
|
PhpAssignmentExpression, PhpExpression, PhpExpressionList, PhpPrimaryExpression, PhpStatement,
|
||||||
};
|
};
|
||||||
@ -8,10 +9,8 @@ use super::PHPTransformable;
|
|||||||
|
|
||||||
/// Transforms a THP AST into a PHP AST
|
/// Transforms a THP AST into a PHP AST
|
||||||
impl<'a> PHPTransformable<'a> for ModuleAST<'_> {
|
impl<'a> PHPTransformable<'a> for ModuleAST<'_> {
|
||||||
type Item = PhpAst<'a>;
|
fn into_php_ast(&'a self) -> Box<(dyn Transpilable + 'a)>{
|
||||||
|
let mut php_statements = Vec::<_>::new();
|
||||||
fn into_php_ast(&'a self) -> Self::Item {
|
|
||||||
let mut php_statements = Vec::<PhpStatement>::new();
|
|
||||||
|
|
||||||
for production in self.productions.iter() {
|
for production in self.productions.iter() {
|
||||||
match production {
|
match production {
|
||||||
@ -44,33 +43,33 @@ impl<'a> PHPTransformable<'a> for ModuleAST<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
php_statements.push(PhpStatement::PhpEchoStatement(PhpExpressionList {
|
php_statements.push(Box::new(PhpStatement::PhpEchoStatement(PhpExpressionList {
|
||||||
expressions
|
expressions
|
||||||
}));
|
})));
|
||||||
},
|
},
|
||||||
_ => todo!("Not implemented: AST transformation for function call that is not an identifier")
|
_ => todo!("Not implemented: AST transformation for function call that is not an identifier")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::Int(value) => {
|
Expression::Int(value) => {
|
||||||
php_statements.push(PhpStatement::PhpExpressionStatement(
|
php_statements.push(Box::new(PhpStatement::PhpExpressionStatement(
|
||||||
PhpExpression::Assignment(PhpAssignmentExpression::Primary(
|
PhpExpression::Assignment(PhpAssignmentExpression::Primary(
|
||||||
PhpPrimaryExpression::IntegerLiteral(&value.value),
|
PhpPrimaryExpression::IntegerLiteral(&value.value),
|
||||||
)),
|
)),
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
Expression::Float(value) => {
|
Expression::Float(value) => {
|
||||||
php_statements.push(PhpStatement::PhpExpressionStatement(
|
php_statements.push(Box::new(PhpStatement::PhpExpressionStatement(
|
||||||
PhpExpression::Assignment(PhpAssignmentExpression::Primary(
|
PhpExpression::Assignment(PhpAssignmentExpression::Primary(
|
||||||
PhpPrimaryExpression::FloatingLiteral(&value.value),
|
PhpPrimaryExpression::FloatingLiteral(&value.value),
|
||||||
)),
|
)),
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
Expression::String(value) => {
|
Expression::String(value) => {
|
||||||
php_statements.push(PhpStatement::PhpExpressionStatement(
|
php_statements.push(Box::new(PhpStatement::PhpExpressionStatement(
|
||||||
PhpExpression::Assignment(PhpAssignmentExpression::Primary(
|
PhpExpression::Assignment(PhpAssignmentExpression::Primary(
|
||||||
PhpPrimaryExpression::StringLiteral(&value.value),
|
PhpPrimaryExpression::StringLiteral(&value.value),
|
||||||
)),
|
)),
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
todo!("not implemented: AST transform for expression {:?}", expr)
|
todo!("not implemented: AST transform for expression {:?}", expr)
|
||||||
@ -80,12 +79,13 @@ impl<'a> PHPTransformable<'a> for ModuleAST<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PhpAst {
|
Box::new(PhpAst {
|
||||||
statements: php_statements,
|
statements: php_statements,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{php_ast::transformers::PHPTransformable, syntax::ast::ModuleAST};
|
use crate::{php_ast::transformers::PHPTransformable, syntax::ast::ModuleAST};
|
||||||
@ -100,3 +100,4 @@ mod tests {
|
|||||||
assert!(output.statements.is_empty())
|
assert!(output.statements.is_empty())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -1,21 +1,19 @@
|
|||||||
use super::super::PhpStatement;
|
use super::super::PhpStatement;
|
||||||
use crate::{
|
use crate::{
|
||||||
php_ast::{PhpAssignmentExpression, PhpExpression, PhpSimpleAssignment},
|
codegen::Transpilable, php_ast::{PhpAssignmentExpression, PhpExpression, PhpSimpleAssignment}, syntax::ast::Statement
|
||||||
syntax::ast::Statement,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::PHPTransformable;
|
use super::PHPTransformable;
|
||||||
|
|
||||||
/// Transforms a THP expression into a PHP expression
|
/// Transforms a THP expression into a PHP expression
|
||||||
impl<'a> PHPTransformable<'a> for Statement<'_> {
|
impl<'a> PHPTransformable<'a> for Statement<'_> {
|
||||||
type Item = PhpStatement<'a>;
|
fn into_php_ast(&'a self) -> Box<(dyn Transpilable + 'a)>{
|
||||||
|
|
||||||
fn into_php_ast(&'a self) -> Self::Item {
|
|
||||||
match self {
|
match self {
|
||||||
Statement::Binding(b) => {
|
Statement::Binding(b) => {
|
||||||
// This is a PhpExpression, but a PhpPrimaryExpression is needed
|
// This is a PhpExpression, but a PhpPrimaryExpression is needed
|
||||||
let binding_expr = b.expression.into_php_ast();
|
let binding_expr = b.expression.into_php_ast();
|
||||||
|
|
||||||
|
/*
|
||||||
// TODO: Somehow fix this...
|
// TODO: Somehow fix this...
|
||||||
// the function above `into_php_ast` should somehow
|
// the function above `into_php_ast` should somehow
|
||||||
// return what I need? Or should return something general and
|
// return what I need? Or should return something general and
|
||||||
@ -27,19 +25,21 @@ impl<'a> PHPTransformable<'a> for Statement<'_> {
|
|||||||
PhpExpression::Assignment(PhpAssignmentExpression::Primary(p)) => p,
|
PhpExpression::Assignment(PhpAssignmentExpression::Primary(p)) => p,
|
||||||
_ => unreachable!("Expected a PrimaryExpression during AST transformation"),
|
_ => unreachable!("Expected a PrimaryExpression during AST transformation"),
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
PhpStatement::PhpExpressionStatement(PhpExpression::Assignment(
|
Box::new(PhpStatement::PhpExpressionStatement(PhpExpression::Assignment(
|
||||||
PhpAssignmentExpression::SimpleAssignment(PhpSimpleAssignment {
|
PhpAssignmentExpression::SimpleAssignment(PhpSimpleAssignment {
|
||||||
variable: b.identifier.value.clone(),
|
variable: b.identifier.value.clone(),
|
||||||
assignment: binding_primary_expr,
|
assignment: binding_expr,
|
||||||
}),
|
}),
|
||||||
))
|
)))
|
||||||
}
|
}
|
||||||
_ => todo!("transformation for statement: {:?}", self),
|
_ => todo!("transformation for statement: {:?}", self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -86,3 +86,4 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user