| 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 | 2 | |
| 3 | 3 | pub mod ast; |
| 4 | 4 | pub mod tokenizer; |
| 5 | pub mod walker; | |
| 5 | pub mod printer; | |
| 6 | 6 | |
| 7 | 7 | pub mod util; |
| 8 | 8 | |
| ... | ... | @@ -14,7 +14,7 @@ pub fn transpile(content: String) -> Result<String> { |
| 14 | 14 | // 3. Type check the AST |
| 15 | 15 | // type_check(tree.clone())?; |
| 16 | 16 | // 4. Transpile the AST into javascript |
| 17 | let result = walker::transpile(tree)?; | |
| 17 | let result = printer::transpile(tree)?; | |
| 18 | 18 | // 5. Return the javascript |
| 19 | 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 | } |