From bb54c6a1241b07ba51cc12791c85704953f095ae Mon Sep 17 00:00:00 2001 From: dkanus Date: Tue, 16 Sep 2025 08:23:53 +0700 Subject: [PATCH] Update dev tests to work with incomplete parser --- dev_tests/Cargo.toml | 4 + dev_tests/src/dump_tokens.rs | 2 +- dev_tests/src/temp.rs | 129 +++++++++++++++++++++++++++++++ dev_tests/src/uc_lexer_verify.rs | 4 +- 4 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 dev_tests/src/temp.rs diff --git a/dev_tests/Cargo.toml b/dev_tests/Cargo.toml index 7c528e3..70f7783 100644 --- a/dev_tests/Cargo.toml +++ b/dev_tests/Cargo.toml @@ -11,6 +11,10 @@ path = "src/dump_tokens.rs" name = "uc_lexer_verify" path = "src/uc_lexer_verify.rs" +[[bin]] +name = "temp" +path = "src/temp.rs" + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/dev_tests/src/dump_tokens.rs b/dev_tests/src/dump_tokens.rs index 5f25c0a..1a5c846 100644 --- a/dev_tests/src/dump_tokens.rs +++ b/dev_tests/src/dump_tokens.rs @@ -70,7 +70,7 @@ fn main() { let (decoded_str, _, _) = encoding.decode(&raw_bytes); let source_text = decoded_str.to_string(); - let tokenized_file = TokenizedFile::from_source(&source_text); + let tokenized_file = TokenizedFile::from_str(&source_text); tokenized_file.dump_debug_layout(); } diff --git a/dev_tests/src/temp.rs b/dev_tests/src/temp.rs new file mode 100644 index 0000000..34cd8af --- /dev/null +++ b/dev_tests/src/temp.rs @@ -0,0 +1,129 @@ +//! src/main.rs +//! -------------------------------------------- +//! Build & run: +//! cargo run +//! -------------------------------------------- + +use std::env; +use std::fs; +use std::io::{self, Read, Write}; +use std::path::Path; + +use rottlib::arena::Arena; +use rottlib::lexer::TokenizedFile; +use rottlib::parser::{ParseError, Parser, pretty::ExprTree}; + +/* +- Convenient array definitions: [1, 3, 5, 2, 4] +- Boolean dynamic arrays +- Structures in default properties +- Auto conversion of arrays into strings +- Making 'var' and 'local' unnecessary +- Allowing variable creation in 'for' loops +- Allowing variable creation at any place inside a function +- Default parameters for functions +- Function overloading? +- repeat/until +- The syntax of the default properties block is pretty strict for an arcane reason. Particularly adding spaces before or after the "=" will lead to errors in pre-UT2003 versions. +- Scopes +- different names for variables and in config file +- anonymous pairs (objects?) and value destruction +>>> AST > HIR > MIR > byte code +*/ + +/// Closest plan: +/// - Add top-level declaration parsing +/// - Handle pretty.rs shit somehow +/// - COMMITS +/// --------------------------------------- +/// - Add fancy error reporting +/// - Make a fancy REPL +/// - Add evaluation +/// +/// WARNINGS: +/// - Empty code/switch blocks + +fn parse_and_print(src: &str) -> Result<(), ParseError> { + let tokenized = TokenizedFile::from_str(src); + let arena = Arena::new(); + let mut parser = Parser::new(&tokenized, &arena); + + let expr = parser.parse_expression(); // ArenaNode + println!("{}", ExprTree(&*expr)); // if ArenaNode + // or: println!("{}", ExprTree(expr.as_ref())); // if no Deref + Ok(()) +} + +fn repl_once() -> Result<(), ParseError> { + print!("Enter an statement > "); + io::stdout().flush().unwrap(); + + let mut input = String::new(); + if io::stdin().read_line(&mut input).is_err() { + eprintln!("failed to read input"); + return Ok(()); + } + + if input.trim().is_empty() { + return Ok(()); + } + + parse_and_print(&input) +} + +fn read_stdin_all() -> io::Result { + let mut buf = String::new(); + io::stdin().read_to_string(&mut buf)?; + Ok(buf) +} + +fn read_file_to_string(path: &Path) -> io::Result { + fs::read_to_string(path) +} + +fn main() -> Result<(), ParseError> { + // Accept a single positional arg as the input path. + // "-" means read all of stdin. + let mut args = env::args().skip(1); + + if let Some(arg1) = args.next() { + if arg1 == "-h" || arg1 == "--help" { + println!("Usage:"); + println!( + " {} # REPL", + env::args().next().unwrap_or_else(|| "prog".into()) + ); + println!( + " {} # parse file", + env::args().next().unwrap_or_else(|| "prog".into()) + ); + println!( + " {} - # read source from stdin", + env::args().next().unwrap_or_else(|| "prog".into()) + ); + return Ok(()); + } + + if arg1 == "-" { + match read_stdin_all() { + Ok(src) => return parse_and_print(&src), + Err(e) => { + eprintln!("stdin read error: {}", e); + return Ok(()); + } + } + } else { + let path = Path::new(&arg1); + match read_file_to_string(path) { + Ok(src) => return parse_and_print(&src), + Err(e) => { + eprintln!("file read error ({}): {}", path.display(), e); + return Ok(()); + } + } + } + } + + // No filename provided -> keep REPL behavior + repl_once() +} diff --git a/dev_tests/src/uc_lexer_verify.rs b/dev_tests/src/uc_lexer_verify.rs index 2b8cf4b..30273c6 100644 --- a/dev_tests/src/uc_lexer_verify.rs +++ b/dev_tests/src/uc_lexer_verify.rs @@ -95,8 +95,8 @@ fn main() { let tokenized_files: Vec<(PathBuf, TokenizedFile)> = uc_files .iter() .map(|(path, source_code)| { - let tokenized_file = TokenizedFile::from_source(source_code); - if tokenized_file.had_errors() { + let tokenized_file = TokenizedFile::from_str(source_code); + if tokenized_file.has_errors() { println!("TK: {}", path.display()); } (path.clone(), tokenized_file)