Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A90 Unify the entire way of writing code #61

Merged
merged 2 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ edition = "2021"
heraclitus-compiler = "1.5.8"
similar-string = "1.4.2"
colored = "2.0.0"
itertools = "0.10.5"
itertools = "0.11.0"

[profile.release]
debug = true
8 changes: 4 additions & 4 deletions setup/install.ab
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { hasFailed, includes, exit } from "std"
import { has_failed, includes, exit } from "std"

let name = "AmberNative"
let target = "amber"
Expand Down Expand Up @@ -43,7 +43,7 @@ main {
echo "Installing Amber"

if {
not hasFailed("ruby -v") {
not has_failed("ruby -v") {
let code = "require \"open-uri\"; open(\"{target}\", \"wb\") do |file|; file << open(\"{url}\").read; end"
echo "Using ruby as a download method..."
$sudo ruby -e "{code}"$ failed {
Expand All @@ -52,15 +52,15 @@ main {
exit(1)
}
}
not hasFailed("curl -v") {
not has_failed("curl -v") {
echo "Using curl as a download method..."
$curl -o "{target}" "{url}"$ failed {
echo "Curl failed to download amber."
echo "Something went wrong. Please try again later."
exit(1)
}
}
not hasFailed("wget -V") {
not has_failed("wget -V") {
echo "Using wget as a download method..."
$wget -O "{target}" "{url}"$ failed {
echo "Wget failed to download amber."
Expand Down
22 changes: 11 additions & 11 deletions setup/install.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
function hasFailed__18_v0 {
function has_failed__18_v0 {
local command=$1
eval ${command} > /dev/null 2>&1
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
:
fi;
__AMBER_FUN_hasFailed18_v0=$(echo $__AMBER_STATUS '!=' 0 | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//');
__AMBER_FUN_has_failed18_v0=$(echo $__AMBER_STATUS '!=' 0 | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//');
return 0
};
function exit__19_v0 {
Expand Down Expand Up @@ -73,13 +73,13 @@ fi;
echo ${__AMBER_FUN_exit19_v0__40} > /dev/null 2>&1
fi;
echo "Installing Amber";
hasFailed__18_v0 "ruby -v";
__AMBER_FUN_hasFailed18_v0__46=${__AMBER_FUN_hasFailed18_v0};
hasFailed__18_v0 "curl -v";
__AMBER_FUN_hasFailed18_v0__55=${__AMBER_FUN_hasFailed18_v0};
hasFailed__18_v0 "wget -V";
__AMBER_FUN_hasFailed18_v0__63=${__AMBER_FUN_hasFailed18_v0};
if [ $(echo '!' ${__AMBER_FUN_hasFailed18_v0__46} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
has_failed__18_v0 "ruby -v";
__AMBER_FUN_has_failed18_v0__46=${__AMBER_FUN_has_failed18_v0};
has_failed__18_v0 "curl -v";
__AMBER_FUN_has_failed18_v0__55=${__AMBER_FUN_has_failed18_v0};
has_failed__18_v0 "wget -V";
__AMBER_FUN_has_failed18_v0__63=${__AMBER_FUN_has_failed18_v0};
if [ $(echo '!' ${__AMBER_FUN_has_failed18_v0__46} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
code="require \"open-uri\"; open(\"${__1_target}\", \"wb\") do |file|; file << open(\"${url}\").read; end";
echo "Using ruby as a download method...";
sudo ruby -e "${code}"
Expand All @@ -91,7 +91,7 @@ if [ $__AMBER_STATUS != 0 ]; then
__AMBER_FUN_exit19_v0__52=${__AMBER_FUN_exit19_v0};
echo ${__AMBER_FUN_exit19_v0__52} > /dev/null 2>&1
fi
elif [ $(echo '!' ${__AMBER_FUN_hasFailed18_v0__55} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
elif [ $(echo '!' ${__AMBER_FUN_has_failed18_v0__55} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
echo "Using curl as a download method...";
curl -o "${__1_target}" "${url}"
__AMBER_STATUS=$?;
Expand All @@ -102,7 +102,7 @@ if [ $__AMBER_STATUS != 0 ]; then
__AMBER_FUN_exit19_v0__60=${__AMBER_FUN_exit19_v0};
echo ${__AMBER_FUN_exit19_v0__60} > /dev/null 2>&1
fi
elif [ $(echo '!' ${__AMBER_FUN_hasFailed18_v0__63} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
elif [ $(echo '!' ${__AMBER_FUN_has_failed18_v0__63} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
echo "Using wget as a download method...";
wget -O "${__1_target}" "${url}"
__AMBER_STATUS=$?;
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cli_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl CLI {
},
None => {
Message::new_err_msg("No value passed after -e flag")
.comment("You can write code that has to be evaluated after the -e flag")
.comment("Write code to be evaluated after the -e flag")
.show();
std::process::exit(1);
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/condition/failed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl SyntaxModule<ParserMetadata> for Failed {
let message = Message::new_warn_at_token(meta, tok)
.message("Empty failed block")
.comment("You should use 'unsafe' modifier to run commands without handling errors");
meta.messages.push(message);
meta.add_message(message);
}
token(meta, "}")?;
},
Expand Down
2 changes: 1 addition & 1 deletion src/modules/condition/ifcond.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl IfCondition {
// TODO: [A34] Add a comment pointing to the website documentation
let message = Message::new_warn_at_token(meta, tok)
.message("You should use if-chain instead of nested if else statements")
.comment(format!("To surpress this warning, use #[{flag_name}] before the parent function declaration"));
.comment(format!("To suppress this warning, use '{flag_name}' compiler flag"));
meta.add_message(message);
}
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion src/modules/expression/unop/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl SyntaxModule<ParserMetadata> for Cast {
let r_type = self.kind.clone();
let message = Message::new_warn_at_token(meta, tok)
.message(format!("Casting a value of type '{l_type}' value to a '{r_type}' is not recommended"))
.comment(format!("To suppress this warning, use #[{flag_name}] before the parent function declaration"));
.comment(format!("To suppress this warning, use '{flag_name}' compiler flag"));
match (l_type, r_type) {
(Type::Array(left), Type::Array(right)) => {
if *left != *right && !matches!(*left, Type::Bool | Type::Num) && !matches!(*right, Type::Bool | Type::Num) {
Expand Down
4 changes: 2 additions & 2 deletions src/modules/function/declaration_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn skip_function_body(meta: &mut ParserMetadata) -> (usize, usize, bool) {
(index_begin, index_end, is_failable)
}

pub fn handle_existing_function(meta: &ParserMetadata, tok: Option<Token>) -> Result<(), Failure> {
pub fn handle_existing_function(meta: &mut ParserMetadata, tok: Option<Token>) -> Result<(), Failure> {
let name = tok.as_ref().unwrap().word.clone();
handle_identifier_name(meta, &name, tok.clone())?;
if meta.get_fun_declaration(&name).is_some() {
Expand All @@ -50,7 +50,7 @@ pub fn handle_add_function(meta: &mut ParserMetadata, tok: Option<Token>, fun: F
let flag_name = get_ccflag_name(CCFlags::AllowGenericReturn);
let message = Message::new_warn_at_token(meta, tok.clone())
.message("Function has typed arguments but a generic return type")
.comment(format!("To surpress this warning, specify a return type for the function '{name}' or use #[{flag_name}] before the parent function declaration"));
.comment(format!("To suppress this warning, specify a return type for the function '{name}' or use '{flag_name}' compiler flag"));
meta.add_message(message);
}
// Try to add the function to the memory
Expand Down
32 changes: 29 additions & 3 deletions src/modules/variable/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use heraclitus_compiler::prelude::*;
use crate::utils::{metadata::ParserMetadata, context::VariableDecl};
use crate::utils::{metadata::ParserMetadata, context::VariableDecl, cc_flags::{get_ccflag_name, CCFlags}};
use similar_string::find_best_similarity;
use crate::modules::types::{Typed, Type};

Expand Down Expand Up @@ -37,7 +37,7 @@ pub fn variable_name_keywords() -> Vec<&'static str> {
}


pub fn handle_variable_reference(meta: &ParserMetadata, tok: Option<Token>, name: &str) -> Result<VariableDecl, Failure> {
pub fn handle_variable_reference(meta: &mut ParserMetadata, tok: Option<Token>, name: &str) -> Result<VariableDecl, Failure> {
handle_identifier_name(meta, name, tok.clone())?;
match meta.get_var(name) {
Some(variable_unit) => Ok(variable_unit.clone()),
Expand All @@ -59,7 +59,7 @@ fn handle_similar_variable(meta: &ParserMetadata, name: &str) -> Option<String>
.and_then(|(match_name, score)| (score >= 0.75).then(|| format!("Did you mean '{match_name}'?")))
}

pub fn handle_identifier_name(meta: &ParserMetadata, name: &str, tok: Option<Token>) -> Result<(), Failure> {
pub fn handle_identifier_name(meta: &mut ParserMetadata, name: &str, tok: Option<Token>) -> Result<(), Failure> {
// Validate if the variable name uses the reserved prefix
if name.chars().take(2).all(|chr| chr == '_') && name.len() > 2 {
let new_name = name.get(1..).unwrap();
Expand All @@ -68,13 +68,39 @@ pub fn handle_identifier_name(meta: &ParserMetadata, name: &str, tok: Option<Tok
comment: format!("Identifiers with double underscores are reserved for the compiler.\nConsider using '{new_name}' instead.")
})
}
if is_camel_case(name) && !meta.context.cc_flags.contains(&CCFlags::AllowCamelCase) {
let flag = get_ccflag_name(CCFlags::AllowCamelCase);
let msg = Message::new_warn_at_token(meta, tok.clone())
.message(format!("Indentifier '{name}' is not in snake case"))
.comment([
"We recommend using snake case with either all uppercase or all lowercase letters for consistency.",
format!("To disable this warning use '{flag}' compiler flag").as_str()
].join("\n"));
meta.add_message(msg);
}
// Validate if the variable name is a keyword
if variable_name_keywords().contains(&name) {
return error!(meta, tok, format!("Indentifier '{name}' is a reserved keyword"))
}
Ok(())
}

fn is_camel_case(name: &str) -> bool {
let mut is_lowercase = false;
let mut is_uppercase = false;
for chr in name.chars() {
match chr {
'_' => continue,
_ if is_lowercase && is_uppercase => return true,
_ if chr.is_lowercase() => is_lowercase = true,
_ if chr.is_uppercase() => is_uppercase = true,
_ => ()
}
}
if is_lowercase && is_uppercase { return true }
false
}

pub fn handle_index_accessor(meta: &mut ParserMetadata) -> Result<Option<Expr>, Failure> {
if token(meta, "[").is_ok() {
let tok = meta.get_current_token();
Expand Down
3 changes: 3 additions & 0 deletions src/utils/cc_flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ pub enum CCFlags {
AllowNestedIfElse,
AllowGenericReturn,
AllowAbsurdCast,
AllowCamelCase,
UndefinedFlag
}

pub fn get_ccflag_by_name(flag: &str) -> CCFlags {
match flag {
"allow_nested_if_else" => CCFlags::AllowNestedIfElse,
"allow_generic_return" => CCFlags::AllowGenericReturn,
"allow_camel_case" => CCFlags::AllowCamelCase,
"allow_absurd_cast" => CCFlags::AllowAbsurdCast,
_ => CCFlags::UndefinedFlag
}
Expand All @@ -21,6 +23,7 @@ pub fn get_ccflag_name(flag: CCFlags) -> &'static str {
CCFlags::AllowNestedIfElse => "allow_nested_if_else",
CCFlags::AllowGenericReturn => "allow_generic_return",
CCFlags::AllowAbsurdCast => "allow_absurd_cast",
CCFlags::AllowCamelCase => "allow_camel_case",
CCFlags::UndefinedFlag => "undefined_flag"
}
}
Expand Down