Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ copyright = "GPLv3"
[dependencies]
amber-meta = { path = "meta" }
chrono = "0.4.38"
clap = { version = "4.4.18", features = ["derive"] }
clap = { version = "4.5.20", features = ["derive"] }
clap_complete = "4.5.36"
colored = "2.0.0"
glob = "0.3"
heraclitus-compiler = "1.8.1"
Expand Down
66 changes: 38 additions & 28 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::modules::block::Block;
use crate::translate::check_all_blocks;
use crate::translate::module::TranslateModule;
use crate::utils::{ParserMetadata, TranslateMetadata};
use crate::{rules, Cli};
use crate::rules;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cli is defined in main.rs, and would therefore be unavailable to a library crate, if we ever decide to separate the code into binary and library crates; removing references to it will help with that.

use postprocessor::PostProcessor;
use chrono::prelude::*;
use colored::Colorize;
Expand All @@ -24,20 +24,31 @@ const NO_CODE_PROVIDED: &str = "No code has been provided to the compiler";
const AMBER_DEBUG_PARSER: &str = "AMBER_DEBUG_PARSER";
const AMBER_DEBUG_TIME: &str = "AMBER_DEBUG_TIME";

pub struct CompilerOptions {
pub no_proc: Vec<String>,
pub minify: bool,
}

impl Default for CompilerOptions {
fn default() -> Self {
Self {
no_proc: vec![String::from("*")],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CompilerOptions is used everywhere AmberCompiler is used, which is to say almost everywhere. I do not think the --no-proc and --minify options make sense outside a cargo check or cargo build scenario, so we disable postprocessors for other subcommands. If anyone thinks we need to run postprocessors by default with cargo run, I can add a command line option for that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it would make sense to add an option for run for disabling postprocessors, in case there are problems with it

Copy link
Contributor Author

@hdwalters hdwalters Nov 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is that postprocessors are currently enabled only for check and build, not for run subcommands. Your response implies that they should be enabled by default for run? (with an option to disable)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't use postprocessors at all. Moreover I think that for debugging purposes they should be disabled so that we can see what's actually being returned by amber compiler. Running them make sense when compiling amber in --release mode. Wdyt?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So right now the postprocessors, are a formatter and a a tool that inject code in the bash script.
I think that makes sense when amber is released that the postprocessor are enabled, but we have a tests if I am not wrong for those.

minify: false,
}
}
}

pub struct AmberCompiler {
pub cc: Compiler,
pub path: Option<String>,
pub cli_opts: Cli,
pub options: CompilerOptions,
}

impl AmberCompiler {
pub fn new(code: String, path: Option<String>, cli_opts: Cli) -> AmberCompiler {
AmberCompiler {
cc: Compiler::new("Amber", rules::get_rules()),
path,
cli_opts,
}
.load_code(AmberCompiler::comment_shebang(code))
pub fn new(code: String, path: Option<String>, options: CompilerOptions) -> AmberCompiler {
let cc = Compiler::new("Amber", rules::get_rules());
let compiler = AmberCompiler { cc, path, options };
compiler.load_code(AmberCompiler::comment_shebang(code))
}

fn comment_shebang(code: String) -> String {
Expand Down Expand Up @@ -91,14 +102,9 @@ impl AmberCompiler {
}
}

pub fn parse(
&self,
tokens: Vec<Token>,
is_docs_gen: bool,
) -> Result<(Block, ParserMetadata), Message> {
pub fn parse(&self, tokens: Vec<Token>) -> Result<(Block, ParserMetadata), Message> {
let code = self.cc.code.as_ref().expect(NO_CODE_PROVIDED).clone();
let mut meta = ParserMetadata::new(tokens, self.path.clone(), Some(code));
meta.is_docs_gen = is_docs_gen;
if let Err(Failure::Loud(err)) = check_all_blocks(&meta) {
return Err(err);
}
Expand Down Expand Up @@ -150,7 +156,7 @@ impl AmberCompiler {

pub fn translate(&self, block: Block, meta: ParserMetadata) -> Result<String, Message> {
let ast_forest = self.get_sorted_ast_forest(block, &meta);
let mut meta_translate = TranslateMetadata::new(meta, &self.cli_opts);
let mut meta_translate = TranslateMetadata::new(meta, &self.options);
let time = Instant::now();
let mut result = vec![];
for (_path, block) in ast_forest {
Expand All @@ -167,7 +173,7 @@ impl AmberCompiler {

let mut result = result.join("\n") + "\n";

let filters = self.cli_opts.no_proc.iter()
let filters = self.options.no_proc.iter()
.map(|x| WildMatchPattern::new(x))
.collect();
let postprocessors = PostProcessor::filter_default(filters);
Expand All @@ -185,13 +191,10 @@ impl AmberCompiler {
};
}

let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
let header = include_str!("header.sh")
.replace("{{ version }}", env!("CARGO_PKG_VERSION"))
.replace("{{ date }}", Local::now()
.format("%Y-%m-%d %H:%M:%S")
.to_string()
.as_str()
);
.replace("{{ date }}", now.as_str());
Ok(format!("{}{}", header, result))
}

Expand Down Expand Up @@ -255,32 +258,39 @@ impl AmberCompiler {

pub fn compile(&self) -> Result<(Vec<Message>, String), Message> {
let tokens = self.tokenize()?;
let (block, meta) = self.parse(tokens, false)?;
let (block, meta) = self.parse(tokens)?;
let messages = meta.messages.clone();
let code = self.translate(block, meta)?;
Ok((messages, code))
}

pub fn execute(code: String, flags: &[String]) -> Result<ExitStatus, std::io::Error> {
pub fn execute(mut code: String, args: Vec<String>) -> Result<ExitStatus, std::io::Error> {
if let Some(mut command) = Self::find_bash() {
let code = format!("set -- {};\n{}", flags.join(" "), code);
if !args.is_empty() {
let args = args.into_iter()
.map(|arg| arg.replace("\"", "\\\""))
.map(|arg| format!("\"{arg}\""))
.collect::<Vec<String>>();
code = format!("set -- {}\n{}", args.join(" "), code);
}
command.arg("-c").arg(code).spawn()?.wait()
} else {
let error = std::io::Error::new(ErrorKind::NotFound, "Failed to find Bash");
Err(error)
}
}

pub fn generate_docs(&self, output: String) -> Result<(), Message> {
pub fn generate_docs(&self, output: String, usage: bool) -> Result<(), Message> {
let tokens = self.tokenize()?;
let (block, meta) = self.parse(tokens, true)?;
let (block, mut meta) = self.parse(tokens)?;
meta.doc_usage = usage;
self.document(block, meta, output);
Ok(())
}

#[cfg(test)]
pub fn test_eval(&mut self) -> Result<String, Message> {
self.cli_opts.no_proc = vec!["*".into()];
self.options.no_proc = vec!["*".into()];
self.compile().map_or_else(Err, |(_, code)| {
if let Some(mut command) = Self::find_bash() {
let child = command.arg("-c").arg::<&str>(code.as_ref()).output().unwrap();
Expand Down
Loading