From 6c0b63b95cbe23c405fd9f0bfe6c3fab42e83114 Mon Sep 17 00:00:00 2001 From: me Date: Fri, 26 Dec 2025 18:38:55 +0200 Subject: [PATCH] include --- programs/map.ayin | 13 +--- programs/stdlib.ayin | 31 ++++++++++ src/ast/types.rs | 8 ++- src/ayin.rs | 13 ++-- src/parser/mod.rs | 62 +++++++++++++++++++ src/parser/parser.rs | 3 +- ...parser__parser__tests__let_loop_count.snap | 1 + 7 files changed, 108 insertions(+), 23 deletions(-) create mode 100644 programs/stdlib.ayin diff --git a/programs/map.ayin b/programs/map.ayin index cf42950..9132308 100644 --- a/programs/map.ayin +++ b/programs/map.ayin @@ -1,16 +1,5 @@ -let map = fn(f,array) { - let mut index = 0 - loop { - if index >= array.len { - break - } - array.index = f(array.index) - index = index + 1 - } - array -} +include "./stdlib.ayin" let main = fn() { map(fn (x) { x + 1 }, [1,2,3]) } - diff --git a/programs/stdlib.ayin b/programs/stdlib.ayin new file mode 100644 index 0000000..a6c77f1 --- /dev/null +++ b/programs/stdlib.ayin @@ -0,0 +1,31 @@ +let map = fn(f,array) { + let mut index = 0 + loop { + if index >= array.len { + break + } + array.index = f(array.index) + index = index + 1 + } + array +} + +let min = fn(a,b) { + if a < b { + a + } else { + b + } +} + +let max = fn(a,b) { + if a < b { + b + } else { + a + } +} + +let abs = fn(a) { + if a >= 0 { a } else { 0 - a } +} diff --git a/src/ast/types.rs b/src/ast/types.rs index 1801ee2..2f777f8 100644 --- a/src/ast/types.rs +++ b/src/ast/types.rs @@ -5,10 +5,11 @@ use std::collections::BTreeMap; /// A Program. #[derive(PartialEq, PartialOrd, Debug, Clone)] pub struct Program { + pub includes: Vec, pub defs: Vec, } -#[derive(PartialEq, PartialOrd, Debug, Clone)] +#[derive(PartialEq, Eq, Hash, PartialOrd, Debug, Clone)] pub struct File(pub String); #[derive(PartialEq, PartialOrd, Debug, Clone)] @@ -230,7 +231,10 @@ impl From for Expr { impl From> for Program { fn from(defs: Vec) -> Program { - Program { defs } + Program { + defs, + includes: vec![], + } } } diff --git a/src/ayin.rs b/src/ayin.rs index c830449..decf80d 100644 --- a/src/ayin.rs +++ b/src/ayin.rs @@ -1,15 +1,12 @@ fn main() { - match read_file() { + let args: Vec = std::env::args().collect(); + let file = args[1].clone(); + + match ayin::parser::parse_program(&file) { Err(err) => println!("Error: {err:#?}"), - Ok(txt) => match ayin::run_main(&txt) { + Ok(program) => match ayin::interpret::run(program, "main".into(), vec![]) { Err(err) => println!("Error: {err:#?}"), Ok(e) => println!("{e:#?}"), }, } } - -fn read_file() -> std::io::Result { - let args: Vec = std::env::args().collect(); - let file = args[1].clone(); - std::fs::read_to_string(file) -} diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 2838459..17cb85e 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -3,7 +3,69 @@ pub mod parser; pub mod scanner; pub mod types; +use std::collections::HashMap; + pub fn parse_file(code: String) -> Result { let mut tokens = scanner::scan(code); parser::parse(&mut tokens, parser::parse_program) } + +pub fn parse_program(file: &String) -> Result { + let file = std::path::Path::new(&file).canonicalize().unwrap(); + let file = crate::ast::File(file.to_str().unwrap().into()); + let mut programs: HashMap = HashMap::new(); + parse_files(&file, &mut programs)?; + let mut defs: Vec = vec![]; + for (_, program) in programs.iter_mut() { + defs.append(&mut program.defs); + } + Ok(crate::ast::Program { + defs, + includes: vec![], + }) +} + +fn parse_files( + file: &crate::ast::File, + programs: &mut HashMap, +) -> Result<(), Error> { + if programs.get(file).is_some() { + return Ok(()); + } + match std::fs::read_to_string(&file.0) { + Err(err) => Err(Error::IO(err)), + Ok(code) => match parse_file(code) { + Err(err) => Err(Error::Parser(err)), + Ok(program) => { + let includes = program.includes.clone(); + programs.insert(file.clone(), program); + for include in includes { + let p = get_dir(file); + let parent = std::path::Path::new(&p); + let file = std::path::Path::new(&include.0); + let file = parent.join(file); + let file = file.to_str().unwrap().to_string(); + parse_files(&crate::ast::File(file), programs)?; + } + Ok(()) + } + }, + } +} + +fn get_dir(file: &crate::ast::File) -> String { + std::path::Path::new(&file.0) + .canonicalize() + .unwrap() + .parent() + .unwrap() + .to_str() + .unwrap() + .to_string() +} + +#[derive(Debug)] +pub enum Error { + Parser(types::Error), + IO(std::io::Error), +} diff --git a/src/parser/parser.rs b/src/parser/parser.rs index c3f7bbe..9be470d 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -15,7 +15,8 @@ pub fn parse(tokens: &mut Tokens, parser: Parser) -> Result { } pub fn parse_program(tokens: &mut Tokens) -> ParseResult { - Ok(parse_definitions(tokens)?.map(|defs| ast::Program { defs })) + let includes = parse_includes(tokens)?.unwrap_or(vec![]); + Ok(parse_definitions(tokens)?.map(|defs| ast::Program { defs, includes })) } fn parse_includes(tokens: &mut Tokens) -> ParseResult> { diff --git a/src/parser/snapshots/ayin__parser__parser__tests__let_loop_count.snap b/src/parser/snapshots/ayin__parser__parser__tests__let_loop_count.snap index 5d87810..5a42f03 100644 --- a/src/parser/snapshots/ayin__parser__parser__tests__let_loop_count.snap +++ b/src/parser/snapshots/ayin__parser__parser__tests__let_loop_count.snap @@ -4,6 +4,7 @@ expression: result --- Ok( Program { + includes: [], defs: [ Definition { mutable: false,