1+ use std:: fs;
2+ use std:: io:: Write ;
13use clap:: { Arg , Command } ;
24use rust_embed:: RustEmbed ;
35use boa_engine:: { Context , Source , JsValue , JsString } ;
4- use std:: fs;
5- use std:: io:: Write ;
66
77#[ derive( RustEmbed ) ]
88#[ folder = "abcodejs/" ]
99struct Asset ;
1010
11- const PRE_HEADER : & str = r#"// © 2021-2025 by César Andres Arcila Buitrago
12-
13- const console = {
14- messages: [],
15- log: function(message) {
16- this.messages.push("LOG: " + message);
17- },
18- warn: function(message) {
19- this.messages.push("WARN: " + message);
20- },
21- error: function(message) {
22- this.messages.push("ERROR: " + message);
23- }
24- }
25-
26- function getConsoleMessages() {
27- return console.messages.join('\n');
28- }
29-
30- String.prototype.substr = function(start, length) {
31- if (start < 0) {
32- start = this.length + start;
33- if (start < 0) start = 0;
34- }
35- if (length === undefined) {
36- return this.substring(start);
37- }
38- if (length < 0) {
39- return '';
40- }
41- return this.substring(start, start + length);
42- }
43- "# ;
44-
4511fn main ( ) {
46- // Configuración de Clap para parsear los argumentos de línea de comandos
12+ // Setting Clap for command line arguments
4713 let matches = Command :: new ( "abcodec" )
48- . version ( "1 .0" )
49- . about ( "ABCode transpiler " )
14+ . version ( "0.3 .0" )
15+ . about ( "ABCode Compiler (Transpiler) " )
5016 . arg (
5117 Arg :: new ( "target" )
5218 . short ( 't' )
@@ -69,7 +35,7 @@ fn main() {
6935 let plan = "*" ;
7036 let output = "./run/" ;
7137
72- // Mensaje inicial
38+ // Initial message
7339 println ! (
7440 "\n INIT => target: {} | script: {} | plan: {} | output: {} | os: {}\n " ,
7541 target,
@@ -79,7 +45,7 @@ fn main() {
7945 std:: env:: consts:: OS
8046 ) ;
8147
82- // Lógica principal: si target > 6, muestra los targets; si no, procesa el script
48+ // Main logic: In case of target > 6, it shows the target options
8349 if target > 6 {
8450 println ! ( "Target language or runtime: 1. Node.js, 2. Deno, 3. Wasm, 4. Python, 5. Lua, 6. Kotlin" ) ;
8551 } else {
@@ -90,7 +56,7 @@ fn main() {
9056}
9157
9258fn get_new_file ( target : i32 , script_file : & str ) -> String {
93- // Determina la extensión según el target
59+ // Set extension according to the target
9460 let extension = match target {
9561 1 => ".js" , // Node.js
9662 2 => ".ts" , // Deno
@@ -100,28 +66,45 @@ fn get_new_file(target: i32, script_file: &str) -> String {
10066 6 => ".kt" , // Kotlin
10167 _ => ".js" , // Por defecto
10268 } ;
103- // Reemplaza "abc" por "run" y cambia la extensión
69+
70+ // Replace first "abc" with "run"
10471 let newfile = if let Some ( pos) = script_file. find ( "abc" ) {
10572 let ( before, after) = script_file. split_at ( pos) ;
10673 format ! ( "{}run{}" , before, & after[ 3 ..] )
10774 } else {
10875 script_file. to_string ( )
10976 } ;
77+
11078 newfile. replace ( ".abc" , extension)
11179}
11280
81+ macro_rules! get_console_messages {
82+ ( $context: expr) => { {
83+ let console_messages_key = JsString :: from( "getConsole" ) ;
84+ let console_messages_fn = $context
85+ . global_object( )
86+ . get( console_messages_key, & mut $context)
87+ . unwrap( ) ;
88+ let console_messages_fn = console_messages_fn
89+ . as_callable( )
90+ . unwrap( ) ;
91+ let console_messages_result = console_messages_fn
92+ . call( & JsValue :: Undefined , & [ ] , & mut $context)
93+ . unwrap( ) ;
94+ console_messages_result. as_string( ) . unwrap( ) . to_std_string( ) . unwrap( )
95+ } } ;
96+ }
97+
11398fn get_plain_js ( target : i32 , script_file : & str , plan : & str ) {
114- // Crea el directorio de salida si no existe
11599 fs:: create_dir_all ( "./run" ) . unwrap ( ) ;
116100
117- // Calcula el nombre del archivo de salida
118101 let newfile = get_new_file ( target, script_file) ;
119-
120- // Carga el encabezado desde los archivos embebidos
102+ let pre_header_bytes = Asset :: get ( "abchelper.js" ) . unwrap ( ) . data ;
103+ let pre_header_code = String :: from_utf8 ( pre_header_bytes . to_vec ( ) ) . unwrap ( ) ;
121104 let header_bytes = Asset :: get ( "abcode.js" ) . unwrap ( ) . data ;
122105 let header_code = String :: from_utf8 ( header_bytes. to_vec ( ) ) . unwrap ( ) ;
123106
124- // Carga el transpilador según el target
107+ // Load the transpiler file according to the target
125108 let transpiler_file = match target {
126109 1 => "node.js" ,
127110 2 => "deno.js" ,
@@ -131,26 +114,26 @@ fn get_plain_js(target: i32, script_file: &str, plan: &str) {
131114 6 => "kotlin.js" ,
132115 _ => "node.js" ,
133116 } ;
134- let transpiler_bytes = Asset :: get ( transpiler_file) . unwrap ( ) . data ;
117+ let transpiler_bytes = Asset :: get ( transpiler_file) . unwrap_or_else ( || {
118+ panic ! ( "ERROR: Language compiler/transpiler not found for target {}" , target) ;
119+ } ) . data ;
135120 let transpiler_code = String :: from_utf8 ( transpiler_bytes. to_vec ( ) ) . unwrap ( ) ;
136121
137- // Lee el script ABCode desde el archivo
122+ // Read the script file and combine it with the pre-header and header
138123 let script_code = fs:: read_to_string ( script_file) . unwrap ( ) ;
124+ let compiler = format ! ( "{}{}{}" , pre_header_code, header_code, transpiler_code) ;
125+ fs:: write ( "./run/abcodec.js" , & compiler) . unwrap ( ) ; // Save the compiler for debugging
139126
140- // Combina el encabezado y el transpilador
141- let compiler = format ! ( "{}\n {}{}" , PRE_HEADER , header_code, transpiler_code) ;
142- fs:: write ( "./run/abcodec.js" , & compiler) . unwrap ( ) ; // Guarda el compilador (quizás para depuración)
143-
144- // Mensaje de compilación
127+ // Message for the user
145128 print ! ( "Compiling... {}" , script_file) ;
146129 std:: io:: stdout ( ) . flush ( ) . unwrap ( ) ;
147130
148- // Crea un contexto de Boa y evalúa el compilador
131+ // Create Boa context and evaluate the compiler/transpiler
149132 let mut context = Context :: default ( ) ;
150133 let script = Source :: from_bytes ( compiler. as_bytes ( ) ) ;
151134 context. eval ( script) . unwrap ( ) ;
152135
153- // Obtiene la función "start" y la llama con los argumentos
136+ // Get the "start" function from Boa context
154137 let key = JsString :: from ( "start" ) ;
155138 let binding = context
156139 . global_object ( )
@@ -166,26 +149,15 @@ fn get_plain_js(target: i32, script_file: &str, plan: &str) {
166149
167150 let result = start_fn. call ( & JsValue :: Undefined , & args, & mut context) . unwrap ( ) ;
168151 let code = result. as_string ( ) . unwrap ( ) . to_std_string ( ) . unwrap ( ) ;
152+ let console_messages = get_console_messages ! ( context) ;
169153
170- // Obtiene los mensajes de consola
171- let console_messages_key = JsString :: from ( "getConsoleMessages" ) ;
172- let console_messages_fn = context
173- . global_object ( )
174- . get ( console_messages_key, & mut context)
175- . unwrap ( ) ;
176- let console_messages_fn = console_messages_fn
177- . as_callable ( )
178- . unwrap ( ) ;
179- let console_messages_result = console_messages_fn. call ( & JsValue :: Undefined , & [ ] , & mut context) . unwrap ( ) ;
180- let console_messages = console_messages_result. as_string ( ) . unwrap ( ) . to_std_string ( ) . unwrap ( ) ;
181-
182- // Muestra el resultado y lo guarda
154+ // Show the result and save it in the new file
183155 println ! ( " Ok!\n Generating... {}" , newfile) ;
184- println ! ( "---\n {:? } \n " , code ) ;
185- println ! ( "---\n {}" , console_messages ) ;
156+ println ! ( "---\n {} \n " , console_messages ) ;
157+ println ! ( "---\n {}" , code ) ;
186158 fs:: write ( & newfile, & code) . unwrap ( ) ;
187159
188- // Genera el script de compilación/ejecución
160+ // Generate the shell script for compiling the new file
189161 compile_target ( target, & newfile) ;
190162}
191163
@@ -219,7 +191,7 @@ fn compile_target(target: i32, file: &str) {
219191 _ => return ,
220192 } ;
221193
222- // Guarda el script en ./run/abctest.sh
194+ // Save the shell script
223195 let shell = "./run/abctest.sh" ;
224196 fs:: write ( shell, compiler) . unwrap ( ) ;
225197}
0 commit comments