| author | |
| committer | |
| log | 30d91f57ad954a930871abb4d9bfe9028b66f0b9 |
| tree | e16ffc1efa256eb43d5f55b88e4196d224046ecd |
| parent | cbd76a10233a219727ef576f0dee88eb5902f798 |
3 files changed, 141 insertions(+), 141 deletions(-)
compiler/src/lib.rs+2-2| ... | @@ -2,7 +2,7 @@ use miette::Result; | ... | @@ -2,7 +2,7 @@ use miette::Result; |
| 2 | 2 | ||
| 3 | pub mod ast; | 3 | pub mod ast; |
| 4 | pub mod tokenizer; | 4 | pub mod tokenizer; |
| 5 | pub mod walker; | 5 | pub mod printer; |
| 6 | 6 | ||
| 7 | pub mod util; | 7 | pub mod util; |
| 8 | 8 | ||
| ... | @@ -14,7 +14,7 @@ pub fn transpile(content: String) -> Result<String> { | ... | @@ -14,7 +14,7 @@ pub fn transpile(content: String) -> Result<String> { |
| 14 | // 3. Type check the AST | 14 | // 3. Type check the AST |
| 15 | // type_check(tree.clone())?; | 15 | // type_check(tree.clone())?; |
| 16 | // 4. Transpile the AST into javascript | 16 | // 4. Transpile the AST into javascript |
| 17 | let result = walker::transpile(tree)?; | 17 | let result = printer::transpile(tree)?; |
| 18 | // 5. Return the javascript | 18 | // 5. Return the javascript |
| 19 | return Ok(result); | 19 | return Ok(result); |
| 20 | } | 20 | } |
compiler/src/printer/mod.rs created+139| ... | @@ -0,0 +1,139 @@ | ||
| 1 | use miette::Result; | ||
| 2 | |||
| 3 | use super::ast::{Ast, Type}; | ||
| 4 | |||
| 5 | fn transpile_helper(tree: &Ast) -> Result<String> { | ||
| 6 | Ok(match tree { | ||
| 7 | Ast::Number(number) => format!("{}", number), | ||
| 8 | Ast::Identifier(name) => format!("{}", name), | ||
| 9 | Ast::Bool(value) => format!("{}", value), | ||
| 10 | Ast::String(value) => format!("\"{}\"", value), | ||
| 11 | Ast::Comment(comment) => format!("// {}\n", comment), | ||
| 12 | Ast::DocComment(comment) => format!("/** {} */\n", comment), | ||
| 13 | Ast::Operation { | ||
| 14 | operator, | ||
| 15 | left, | ||
| 16 | right, | ||
| 17 | } => format!( | ||
| 18 | "{} {} {}", | ||
| 19 | transpile_helper(left)?, | ||
| 20 | operator.clone().to_string(), | ||
| 21 | transpile_helper(right)? | ||
| 22 | ), | ||
| 23 | Ast::Public { value } => format!("export {}", transpile_helper(value)?), | ||
| 24 | Ast::VariableDeclaration { | ||
| 25 | name, | ||
| 26 | return_type, | ||
| 27 | value, | ||
| 28 | } => match return_type { | ||
| 29 | Type::Bigint => format!("let {} = BigInt({});\n", name, transpile_helper(value)?), | ||
| 30 | _ => format!("let {} = {};\n", name, transpile_helper(value)?), | ||
| 31 | }, | ||
| 32 | Ast::ConstantDeclaration { | ||
| 33 | name, | ||
| 34 | return_type, | ||
| 35 | value, | ||
| 36 | } => match return_type { | ||
| 37 | Type::Bigint => format!("const {} = BigInt({});\n", name, transpile_helper(value)?), | ||
| 38 | _ => format!("const {} = {};\n", name, transpile_helper(value)?), | ||
| 39 | }, | ||
| 40 | Ast::Return { return_value } => format!("return {};\n", transpile_helper(return_value)?), | ||
| 41 | Ast::Function { | ||
| 42 | name, | ||
| 43 | arguments, | ||
| 44 | return_type: _, | ||
| 45 | block, | ||
| 46 | } => { | ||
| 47 | let mut result = format!("function {}(", name); | ||
| 48 | |||
| 49 | for (i, argument) in arguments.iter().enumerate() { | ||
| 50 | if i == 0 { | ||
| 51 | result += argument.name.as_str(); | ||
| 52 | } else { | ||
| 53 | result += format!(", {}", argument.name).as_str(); | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | result += ") {\n"; | ||
| 58 | |||
| 59 | for (i, statement) in block.value.iter().enumerate() { | ||
| 60 | if block.implicit_return && i == block.value.len() - 1 { | ||
| 61 | result += format!("return {};\n", transpile_helper(statement)?).as_str(); | ||
| 62 | break; | ||
| 63 | } | ||
| 64 | result += transpile_helper(statement)?.as_str(); | ||
| 65 | } | ||
| 66 | |||
| 67 | result += "}\n"; | ||
| 68 | |||
| 69 | result | ||
| 70 | } | ||
| 71 | Ast::If { | ||
| 72 | condition, | ||
| 73 | value, | ||
| 74 | else_value, | ||
| 75 | } => { | ||
| 76 | let mut result = format!("if ({}) {{\n", transpile_helper(condition)?,); | ||
| 77 | |||
| 78 | for (i, statement) in value.value.iter().enumerate() { | ||
| 79 | if value.implicit_return && i == value.value.len() - 1 { | ||
| 80 | result += format!("return {};\n", transpile_helper(statement)?).as_str(); | ||
| 81 | break; | ||
| 82 | } | ||
| 83 | result += transpile_helper(statement)?.as_str(); | ||
| 84 | } | ||
| 85 | |||
| 86 | result += "}"; | ||
| 87 | |||
| 88 | if let Some(val) = else_value { | ||
| 89 | result += format!(" else {{\n{}}}", transpile_helper(val)?).as_str(); | ||
| 90 | } else { | ||
| 91 | result += "\n"; | ||
| 92 | } | ||
| 93 | |||
| 94 | result | ||
| 95 | } | ||
| 96 | Ast::FunctionCall { name, arguments } => { | ||
| 97 | let mut result = match name.as_str() { | ||
| 98 | "print" => String::from("console.log("), | ||
| 99 | _ => format!("{}(", name), | ||
| 100 | }; | ||
| 101 | |||
| 102 | for (i, argument) in arguments.iter().enumerate() { | ||
| 103 | if i == 0 { | ||
| 104 | result += transpile_helper(argument)?.as_str(); | ||
| 105 | } else { | ||
| 106 | result += format!(", {}", transpile_helper(argument)?).as_str(); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | result += ")"; | ||
| 111 | |||
| 112 | result | ||
| 113 | } | ||
| 114 | Ast::Block(block) => { | ||
| 115 | let mut result = String::from("(()=>{\n"); | ||
| 116 | for (i, statement) in block.value.iter().enumerate() { | ||
| 117 | if block.implicit_return && i == block.value.len() - 1 { | ||
| 118 | result += format!("return {};\n", transpile_helper(statement)?).as_str(); | ||
| 119 | break; | ||
| 120 | } | ||
| 121 | result += transpile_helper(statement)?.as_str(); | ||
| 122 | } | ||
| 123 | |||
| 124 | result += "})()\n"; | ||
| 125 | |||
| 126 | result | ||
| 127 | } | ||
| 128 | }) | ||
| 129 | } | ||
| 130 | |||
| 131 | pub fn transpile(forest: Vec<Ast>) -> Result<String> { | ||
| 132 | let mut result = String::new(); | ||
| 133 | |||
| 134 | for tree in forest { | ||
| 135 | result.push_str(&transpile_helper(&tree)?); | ||
| 136 | } | ||
| 137 | |||
| 138 | Ok(result) | ||
| 139 | } | ||
compiler/src/walker.rs deleted-139| ... | @@ -1,139 +0,0 @@ | ||
| 1 | use miette::Result; | ||
| 2 | |||
| 3 | use super::ast::{Ast, Type}; | ||
| 4 | |||
| 5 | fn transpile_helper(tree: &Ast) -> Result<String> { | ||
| 6 | Ok(match tree { | ||
| 7 | Ast::Number(number) => format!("{}", number), | ||
| 8 | Ast::Identifier(name) => format!("{}", name), | ||
| 9 | Ast::Bool(value) => format!("{}", value), | ||
| 10 | Ast::String(value) => format!("\"{}\"", value), | ||
| 11 | Ast::Comment(comment) => format!("// {}\n", comment), | ||
| 12 | Ast::DocComment(comment) => format!("/** {} */\n", comment), | ||
| 13 | Ast::Operation { | ||
| 14 | operator, | ||
| 15 | left, | ||
| 16 | right, | ||
| 17 | } => format!( | ||
| 18 | "{} {} {}", | ||
| 19 | transpile_helper(left)?, | ||
| 20 | operator.clone().to_string(), | ||
| 21 | transpile_helper(right)? | ||
| 22 | ), | ||
| 23 | Ast::Public { value } => format!("export {}", transpile_helper(value)?), | ||
| 24 | Ast::VariableDeclaration { | ||
| 25 | name, | ||
| 26 | return_type, | ||
| 27 | value, | ||
| 28 | } => match return_type { | ||
| 29 | Type::Bigint => format!("let {} = BigInt({});\n", name, transpile_helper(value)?), | ||
| 30 | _ => format!("let {} = {};\n", name, transpile_helper(value)?), | ||
| 31 | }, | ||
| 32 | Ast::ConstantDeclaration { | ||
| 33 | name, | ||
| 34 | return_type, | ||
| 35 | value, | ||
| 36 | } => match return_type { | ||
| 37 | Type::Bigint => format!("const {} = BigInt({});\n", name, transpile_helper(value)?), | ||
| 38 | _ => format!("const {} = {};\n", name, transpile_helper(value)?), | ||
| 39 | }, | ||
| 40 | Ast::Return { return_value } => format!("return {};\n", transpile_helper(return_value)?), | ||
| 41 | Ast::Function { | ||
| 42 | name, | ||
| 43 | arguments, | ||
| 44 | return_type: _, | ||
| 45 | block, | ||
| 46 | } => { | ||
| 47 | let mut result = format!("function {}(", name); | ||
| 48 | |||
| 49 | for (i, argument) in arguments.iter().enumerate() { | ||
| 50 | if i == 0 { | ||
| 51 | result += argument.name.as_str(); | ||
| 52 | } else { | ||
| 53 | result += format!(", {}", argument.name).as_str(); | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | result += ") {\n"; | ||
| 58 | |||
| 59 | for (i, statement) in block.value.iter().enumerate() { | ||
| 60 | if block.implicit_return && i == block.value.len() - 1 { | ||
| 61 | result += format!("return {};\n", transpile_helper(statement)?).as_str(); | ||
| 62 | break; | ||
| 63 | } | ||
| 64 | result += transpile_helper(statement)?.as_str(); | ||
| 65 | } | ||
| 66 | |||
| 67 | result += "}\n"; | ||
| 68 | |||
| 69 | result | ||
| 70 | } | ||
| 71 | Ast::If { | ||
| 72 | condition, | ||
| 73 | value, | ||
| 74 | else_value, | ||
| 75 | } => { | ||
| 76 | let mut result = format!("if ({}) {{\n", transpile_helper(condition)?,); | ||
| 77 | |||
| 78 | for (i, statement) in value.value.iter().enumerate() { | ||
| 79 | if value.implicit_return && i == value.value.len() - 1 { | ||
| 80 | result += format!("return {};\n", transpile_helper(statement)?).as_str(); | ||
| 81 | break; | ||
| 82 | } | ||
| 83 | result += transpile_helper(statement)?.as_str(); | ||
| 84 | } | ||
| 85 | |||
| 86 | result += "}"; | ||
| 87 | |||
| 88 | if let Some(val) = else_value { | ||
| 89 | result += format!(" else {{\n{}}}", transpile_helper(val)?).as_str(); | ||
| 90 | } else { | ||
| 91 | result += "\n"; | ||
| 92 | } | ||
| 93 | |||
| 94 | result | ||
| 95 | } | ||
| 96 | Ast::FunctionCall { name, arguments } => { | ||
| 97 | let mut result = match name.as_str() { | ||
| 98 | "print" => String::from("console.log("), | ||
| 99 | _ => format!("{}(", name), | ||
| 100 | }; | ||
| 101 | |||
| 102 | for (i, argument) in arguments.iter().enumerate() { | ||
| 103 | if i == 0 { | ||
| 104 | result += transpile_helper(argument)?.as_str(); | ||
| 105 | } else { | ||
| 106 | result += format!(", {}", transpile_helper(argument)?).as_str(); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | result += ")"; | ||
| 111 | |||
| 112 | result | ||
| 113 | } | ||
| 114 | Ast::Block(block) => { | ||
| 115 | let mut result = String::from("(()=>{\n"); | ||
| 116 | for (i, statement) in block.value.iter().enumerate() { | ||
| 117 | if block.implicit_return && i == block.value.len() - 1 { | ||
| 118 | result += format!("return {};\n", transpile_helper(statement)?).as_str(); | ||
| 119 | break; | ||
| 120 | } | ||
| 121 | result += transpile_helper(statement)?.as_str(); | ||
| 122 | } | ||
| 123 | |||
| 124 | result += "})()\n"; | ||
| 125 | |||
| 126 | result | ||
| 127 | } | ||
| 128 | }) | ||
| 129 | } | ||
| 130 | |||
| 131 | pub fn transpile(forest: Vec<Ast>) -> Result<String> { | ||
| 132 | let mut result = String::new(); | ||
| 133 | |||
| 134 | for tree in forest { | ||
| 135 | result.push_str(&transpile_helper(&tree)?); | ||
| 136 | } | ||
| 137 | |||
| 138 | Ok(result) | ||
| 139 | } | ||