mirror of
https://github.com/Dummi26/mers.git
synced 2025-04-28 18:16:05 +02:00
-f+c will print the parsed script with colored highlighting
This commit is contained in:
parent
79797e6718
commit
b5924b5da1
@ -20,8 +20,9 @@ for word text.regex("\\S+").assume_no_enum()
|
|||||||
if words > 0 {
|
if words > 0 {
|
||||||
print(word + " ")
|
print(word + " ")
|
||||||
words = words - 1
|
words = words - 1
|
||||||
|
sleep(0.1)
|
||||||
} else if words == 0 {
|
} else if words == 0 {
|
||||||
println(word)
|
println(word)
|
||||||
words = rnd()
|
words = rnd()
|
||||||
sleep(0.75)
|
sleep(0.5)
|
||||||
}
|
}
|
||||||
|
7
mers/Cargo.lock
generated
7
mers/Cargo.lock
generated
@ -159,6 +159,12 @@ dependencies = [
|
|||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorize"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc17e449bc7854c50b943d113a98bc0e01dc6585d2c66eaa09ca645ebd8a7e62"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation-sys"
|
name = "core-foundation-sys"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
@ -643,6 +649,7 @@ dependencies = [
|
|||||||
name = "mers"
|
name = "mers"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"colorize",
|
||||||
"edit",
|
"edit",
|
||||||
"notify",
|
"notify",
|
||||||
"nu-plugin",
|
"nu-plugin",
|
||||||
|
@ -16,6 +16,7 @@ regex = "1.7.2"
|
|||||||
static_assertions = "1.1.0"
|
static_assertions = "1.1.0"
|
||||||
nu-plugin = { version = "0.79.0", optional = true }
|
nu-plugin = { version = "0.79.0", optional = true }
|
||||||
nu-protocol = { version = "0.79.0", features = ["plugin"], optional = true }
|
nu-protocol = { version = "0.79.0", features = ["plugin"], optional = true }
|
||||||
|
colorize = "0.1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# default = ["nushell_plugin"]
|
# default = ["nushell_plugin"]
|
||||||
|
@ -7,6 +7,8 @@ pub mod fs_watcher {
|
|||||||
thread::{self, JoinHandle},
|
thread::{self, JoinHandle},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::lang::fmtgs::FormatGs;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Error(String);
|
pub struct Error(String);
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
io::Write,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
@ -835,9 +836,15 @@ impl BuiltinFunction {
|
|||||||
BuiltinFunction::Print => args[0].run(info).operate_on_data_immut(|v| {
|
BuiltinFunction::Print => args[0].run(info).operate_on_data_immut(|v| {
|
||||||
if let VDataEnum::String(arg) = v {
|
if let VDataEnum::String(arg) = v {
|
||||||
#[cfg(not(feature = "nushell_plugin"))]
|
#[cfg(not(feature = "nushell_plugin"))]
|
||||||
print!("{}", arg);
|
{
|
||||||
|
print!("{}", arg);
|
||||||
|
std::io::stdout().flush();
|
||||||
|
}
|
||||||
#[cfg(feature = "nushell_plugin")]
|
#[cfg(feature = "nushell_plugin")]
|
||||||
eprint!("{}", arg);
|
{
|
||||||
|
eprint!("{}", arg);
|
||||||
|
std::io::stderr().flush();
|
||||||
|
}
|
||||||
VDataEnum::Tuple(vec![]).to()
|
VDataEnum::Tuple(vec![]).to()
|
||||||
} else {
|
} else {
|
||||||
unreachable!("print function called with non-string arg")
|
unreachable!("print function called with non-string arg")
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
use std::fmt::{self, Display, Formatter, Pointer};
|
use std::fmt::{self, Display, Formatter, Pointer};
|
||||||
|
|
||||||
use super::{code_macro::Macro, global_info::GlobalScriptInfo, val_data::VData, val_type::VType};
|
use crate::lang::global_info::ColorFormatMode;
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
code_macro::Macro, fmtgs::FormatGs, global_info::GlobalScriptInfo, val_data::VData,
|
||||||
|
val_type::VType,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SStatementEnum {
|
pub enum SStatementEnum {
|
||||||
@ -82,101 +87,142 @@ impl SFunction {
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
impl SStatementEnum {
|
impl FormatGs for SStatementEnum {
|
||||||
pub fn fmtgs(&self, f: &mut Formatter, info: Option<&GlobalScriptInfo>) -> fmt::Result {
|
fn fmtgs(
|
||||||
|
&self,
|
||||||
|
f: &mut Formatter,
|
||||||
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut super::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::Value(v) => v.fmtgs(f, info),
|
Self::Value(v) => v.fmtgs(f, info, form, file),
|
||||||
Self::Tuple(v) => {
|
Self::Tuple(v) => {
|
||||||
write!(f, "[")?;
|
write!(f, "{}", form.open_bracket(info, "[".to_owned()))?;
|
||||||
for (i, v) in v.iter().enumerate() {
|
for (i, v) in v.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
}
|
}
|
||||||
v.fmtgs(f, info)?;
|
v.fmtgs(f, info, form, file)?;
|
||||||
}
|
}
|
||||||
write!(f, "]")
|
write!(f, "{}", form.close_bracket(info, "]".to_owned()))
|
||||||
}
|
}
|
||||||
Self::List(v) => {
|
Self::List(v) => {
|
||||||
write!(f, "[")?;
|
write!(f, "{}", form.open_bracket(info, "[".to_owned()))?;
|
||||||
for (i, v) in v.iter().enumerate() {
|
for (i, v) in v.iter().enumerate() {
|
||||||
v.fmtgs(f, info)?;
|
v.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
}
|
}
|
||||||
write!(f, "...]")
|
write!(f, "{}", form.close_bracket(info, "...]".to_owned()))
|
||||||
}
|
}
|
||||||
Self::Variable(var, reference) => {
|
Self::Variable(var, reference) => {
|
||||||
if *reference {
|
if *reference {
|
||||||
write!(f, "&{var}")
|
write!(f, "{}", form.variable_ref_symbol(info, "&".to_owned()))?;
|
||||||
} else {
|
|
||||||
write!(f, "{var}")
|
|
||||||
}
|
}
|
||||||
|
write!(f, "{}", form.variable(info, var.to_owned()))
|
||||||
}
|
}
|
||||||
Self::FunctionCall(func, args) => {
|
Self::FunctionCall(func, args) => {
|
||||||
write!(f, "{func}(")?;
|
write!(
|
||||||
for arg in args {
|
f,
|
||||||
arg.fmtgs(f, info)?;
|
"{}{}",
|
||||||
|
form.fncall(info, func.to_owned()),
|
||||||
|
form.open_bracket(info, "(".to_owned())
|
||||||
|
)?;
|
||||||
|
for (i, arg) in args.iter().enumerate() {
|
||||||
|
if i != 0 {
|
||||||
|
write!(f, " ");
|
||||||
|
}
|
||||||
|
arg.fmtgs(f, info, form, file)?;
|
||||||
}
|
}
|
||||||
write!(f, ")")
|
write!(f, "{}", form.close_bracket(info, ")".to_owned()))
|
||||||
}
|
}
|
||||||
Self::FunctionDefinition(name, func) => {
|
Self::FunctionDefinition(name, func) => {
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
write!(f, "{name}")?;
|
write!(
|
||||||
|
f,
|
||||||
|
"{} {}",
|
||||||
|
form.fndef_fn(info, "fn".to_owned()),
|
||||||
|
form.fndef_name(info, name.to_owned())
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
func.fmtgs(f, info)
|
func.fmtgs(f, info, form, file)
|
||||||
}
|
}
|
||||||
Self::Block(b) => b.fmtgs(f, info),
|
Self::Block(b) => b.fmtgs(f, info, form, file),
|
||||||
Self::If(condition, yes, no) => {
|
Self::If(condition, yes, no) => {
|
||||||
write!(f, "if ")?;
|
write!(f, "{} ", form.if_if(info, "if".to_owned()))?;
|
||||||
condition.fmtgs(f, info)?;
|
condition.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
yes.fmtgs(f, info)?;
|
yes.fmtgs(f, info, form, file)?;
|
||||||
if let Some(no) = no {
|
if let Some(no) = no {
|
||||||
write!(f, " else ")?;
|
write!(f, " {} ", form.if_else(info, "else".to_owned()))?;
|
||||||
no.fmtgs(f, info)?;
|
no.fmtgs(f, info, form, file)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Self::Loop(b) => {
|
Self::Loop(b) => {
|
||||||
write!(f, "loop ")?;
|
write!(f, "{} ", form.loop_loop(info, "loop".to_owned()))?;
|
||||||
b.fmtgs(f, info)
|
b.fmtgs(f, info, form, file)
|
||||||
}
|
}
|
||||||
Self::For(var, i, b) => {
|
Self::For(var, i, b) => {
|
||||||
write!(f, "for {} ", var)?;
|
write!(f, "{} {} ", form.loop_for(info, "for".to_owned()), var)?;
|
||||||
i.fmtgs(f, info)?;
|
i.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
b.fmtgs(f, info)
|
b.fmtgs(f, info, form, file)
|
||||||
}
|
}
|
||||||
Self::Switch(var, arms, force) => {
|
Self::Switch(var, arms, force) => {
|
||||||
if *force {
|
if *force {
|
||||||
writeln!(f, "switch! {var} {{")?;
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{} {var} {}",
|
||||||
|
form.kw_switch(info, "switch!".to_owned()),
|
||||||
|
form.open_bracket(info, "{".to_owned())
|
||||||
|
)?;
|
||||||
} else {
|
} else {
|
||||||
writeln!(f, "switch {var} {{")?;
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{} {var} {}",
|
||||||
|
form.kw_switch(info, "switch".to_owned()),
|
||||||
|
form.open_bracket(info, "{".to_owned())
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
form.go_deeper();
|
||||||
for (t, action) in arms {
|
for (t, action) in arms {
|
||||||
t.fmtgs(f, info)?;
|
write!(f, "{}", form.line_prefix())?;
|
||||||
|
t.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
action.fmtgs(f, info)?;
|
action.fmtgs(f, info, form, file)?;
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
}
|
}
|
||||||
write!(f, "}}")
|
form.go_shallower();
|
||||||
|
write!(f, "{}", form.line_prefix())?;
|
||||||
|
write!(f, "{}", form.close_bracket(info, "}".to_owned()))
|
||||||
}
|
}
|
||||||
Self::Match(var, arms) => {
|
Self::Match(var, arms) => {
|
||||||
write!(f, "match {var} {{")?;
|
write!(
|
||||||
|
f,
|
||||||
|
"{} {var} {}",
|
||||||
|
form.kw_match(info, "match".to_owned()),
|
||||||
|
form.open_bracket(info, "{".to_owned())
|
||||||
|
)?;
|
||||||
|
form.go_deeper();
|
||||||
for (condition, action) in arms {
|
for (condition, action) in arms {
|
||||||
condition.fmtgs(f, info)?;
|
write!(f, "{}", form.line_prefix())?;
|
||||||
|
condition.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
action.fmtgs(f, info)?;
|
action.fmtgs(f, info, form, file)?;
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
}
|
}
|
||||||
write!(f, "}}")
|
form.go_shallower();
|
||||||
|
write!(f, "{}", form.line_prefix())?;
|
||||||
|
write!(f, "{}", form.close_bracket(info, "}".to_owned()))
|
||||||
}
|
}
|
||||||
Self::IndexFixed(statement, index) => {
|
Self::IndexFixed(statement, index) => {
|
||||||
statement.fmtgs(f, info)?;
|
statement.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ".{index}")
|
write!(f, ".{index}")
|
||||||
}
|
}
|
||||||
Self::EnumVariant(variant, inner) => {
|
Self::EnumVariant(variant, inner) => {
|
||||||
write!(f, "{variant}: ")?;
|
write!(f, "{variant}: ")?;
|
||||||
inner.fmtgs(f, info)
|
inner.fmtgs(f, info, form, file)
|
||||||
}
|
}
|
||||||
Self::TypeDefinition(name, t) => write!(f, "type {name} {t}"),
|
Self::TypeDefinition(name, t) => write!(f, "type {name} {t}"),
|
||||||
Self::Macro(m) => {
|
Self::Macro(m) => {
|
||||||
@ -187,32 +233,58 @@ impl SStatementEnum {
|
|||||||
}
|
}
|
||||||
impl Display for SStatementEnum {
|
impl Display for SStatementEnum {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
self.fmtgs(f, None)
|
self.fmtgs(f, None, &mut super::fmtgs::FormatInfo::default(), None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SStatement {
|
impl FormatGs for SStatement {
|
||||||
pub fn fmtgs(&self, f: &mut Formatter, info: Option<&GlobalScriptInfo>) -> fmt::Result {
|
fn fmtgs(
|
||||||
|
&self,
|
||||||
|
f: &mut Formatter,
|
||||||
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut super::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
if let Some((opt, derefs)) = &self.output_to {
|
if let Some((opt, derefs)) = &self.output_to {
|
||||||
if let Some(forced_type) = &self.force_output_type {
|
// TODO!
|
||||||
write!(f, "{}{}::", "*".repeat(*derefs), opt)?;
|
match opt.statement.as_ref() {
|
||||||
forced_type.fmtgs(f, info)?;
|
SStatementEnum::Variable(name, is_ref) => {
|
||||||
write!(f, " = ")?;
|
let derefs = if !is_ref { *derefs + 1 } else { *derefs };
|
||||||
} else {
|
write!(
|
||||||
write!(f, "{}{} = ", "*".repeat(*derefs), opt)?;
|
f,
|
||||||
|
"{}{} = ",
|
||||||
|
"*".repeat(derefs),
|
||||||
|
SStatementEnum::Variable(name.to_owned(), false).with(info, file)
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if let Some(forced_type) = &self.force_output_type {
|
||||||
|
write!(f, "{}{}::", "*".repeat(*derefs), opt.with(info, file))?;
|
||||||
|
forced_type.fmtgs(f, info, form, file)?;
|
||||||
|
write!(f, " = ")?;
|
||||||
|
} else {
|
||||||
|
write!(f, "{}{} = ", "*".repeat(*derefs), opt.with(info, file))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.statement.fmtgs(f, info)
|
self.statement.fmtgs(f, info, form, file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Display for SStatement {
|
impl Display for SStatement {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
self.fmtgs(f, None)
|
self.fmtgs(f, None, &mut super::fmtgs::FormatInfo::default(), None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SFunction {
|
impl FormatGs for SFunction {
|
||||||
pub fn fmtgs(&self, f: &mut Formatter, info: Option<&GlobalScriptInfo>) -> fmt::Result {
|
fn fmtgs(
|
||||||
|
&self,
|
||||||
|
f: &mut Formatter,
|
||||||
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut super::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
write!(f, "(")?;
|
write!(f, "(")?;
|
||||||
for (i, (name, t)) in self.inputs.iter().enumerate() {
|
for (i, (name, t)) in self.inputs.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
@ -220,25 +292,35 @@ impl SFunction {
|
|||||||
} else {
|
} else {
|
||||||
write!(f, "{name} ")?;
|
write!(f, "{name} ")?;
|
||||||
}
|
}
|
||||||
t.fmtgs(f, info)?;
|
t.fmtgs(f, info, form, file)?;
|
||||||
}
|
}
|
||||||
write!(f, ") ")?;
|
write!(f, ") ")?;
|
||||||
self.block.fmtgs(f, info)
|
self.block.fmtgs(f, info, form, file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SBlock {
|
impl FormatGs for SBlock {
|
||||||
pub fn fmtgs(&self, f: &mut Formatter, info: Option<&GlobalScriptInfo>) -> fmt::Result {
|
fn fmtgs(
|
||||||
|
&self,
|
||||||
|
f: &mut Formatter,
|
||||||
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut super::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
match self.statements.len() {
|
match self.statements.len() {
|
||||||
0 => write!(f, "{{}}"),
|
0 => write!(f, "{{}}"),
|
||||||
1 => self.statements[0].fmtgs(f, info),
|
// 1 => self.statements[0].fmtgs(f, info, form, file),
|
||||||
_ => {
|
_ => {
|
||||||
writeln!(f, "{{")?;
|
writeln!(f, "{}", form.open_bracket(info, "{".to_owned()))?;
|
||||||
|
form.go_deeper();
|
||||||
for statement in self.statements.iter() {
|
for statement in self.statements.iter() {
|
||||||
statement.fmtgs(f, info)?;
|
write!(f, "{}", form.line_prefix())?;
|
||||||
|
statement.fmtgs(f, info, form, file)?;
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
}
|
}
|
||||||
write!(f, "}}")
|
form.go_shallower();
|
||||||
|
write!(f, "{}", form.line_prefix())?;
|
||||||
|
write!(f, "{}", form.close_bracket(info, "}".to_owned()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,6 @@ impl RStatementEnum {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct RScript {
|
pub struct RScript {
|
||||||
main: RFunction,
|
main: RFunction,
|
||||||
info: GSInfo,
|
info: GSInfo,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
default,
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
@ -8,13 +9,13 @@ use crate::libs;
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
builtins,
|
builtins,
|
||||||
|
fmtgs::Color,
|
||||||
val_data::VDataEnum,
|
val_data::VDataEnum,
|
||||||
val_type::{VSingleType, VType},
|
val_type::{VSingleType, VType},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type GSInfo = Arc<GlobalScriptInfo>;
|
pub type GSInfo = Arc<GlobalScriptInfo>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct GlobalScriptInfo {
|
pub struct GlobalScriptInfo {
|
||||||
pub libs: Vec<libs::Lib>,
|
pub libs: Vec<libs::Lib>,
|
||||||
pub lib_fns: HashMap<String, (usize, usize)>,
|
pub lib_fns: HashMap<String, (usize, usize)>,
|
||||||
@ -24,10 +25,61 @@ pub struct GlobalScriptInfo {
|
|||||||
pub custom_type_names: HashMap<String, usize>,
|
pub custom_type_names: HashMap<String, usize>,
|
||||||
pub custom_types: Vec<VType>,
|
pub custom_types: Vec<VType>,
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
pub formatter: ColorFormatter,
|
||||||
|
|
||||||
pub log: Logger,
|
pub log: Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ColorFormatter {
|
||||||
|
pub mode: ColorFormatMode,
|
||||||
|
pub bracket_colors: Vec<Color>,
|
||||||
|
pub value_string_quotes_color: Color,
|
||||||
|
pub value_string_content_color: Color,
|
||||||
|
pub keyword_if_color: Color,
|
||||||
|
pub keyword_else_color: Color,
|
||||||
|
pub keyword_loop_color: Color,
|
||||||
|
pub keyword_for_color: Color,
|
||||||
|
pub keyword_switch_color: Color,
|
||||||
|
pub keyword_match_color: Color,
|
||||||
|
pub function_call_color: Color,
|
||||||
|
pub function_def_fn_color: Color,
|
||||||
|
pub function_def_name_color: Color,
|
||||||
|
pub variable_color: Color,
|
||||||
|
}
|
||||||
|
impl Default for ColorFormatter {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
mode: ColorFormatMode::Plain,
|
||||||
|
bracket_colors: vec![
|
||||||
|
Color::Red,
|
||||||
|
Color::Yellow,
|
||||||
|
Color::Cyan,
|
||||||
|
Color::Blue,
|
||||||
|
Color::Magenta,
|
||||||
|
],
|
||||||
|
value_string_quotes_color: Color::Grey,
|
||||||
|
value_string_content_color: Color::Cyan,
|
||||||
|
keyword_if_color: Color::Yellow,
|
||||||
|
keyword_else_color: Color::Yellow,
|
||||||
|
keyword_loop_color: Color::Yellow,
|
||||||
|
keyword_for_color: Color::Yellow,
|
||||||
|
keyword_switch_color: Color::Yellow,
|
||||||
|
keyword_match_color: Color::Yellow,
|
||||||
|
function_call_color: Color::Magenta,
|
||||||
|
function_def_fn_color: Color::Blue,
|
||||||
|
function_def_name_color: Color::Magenta,
|
||||||
|
variable_color: Color::Green,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ColorFormatMode {
|
||||||
|
/// No color.
|
||||||
|
Plain,
|
||||||
|
/// For terminal output
|
||||||
|
Colorize,
|
||||||
|
}
|
||||||
|
|
||||||
impl GlobalScriptInfo {
|
impl GlobalScriptInfo {
|
||||||
pub fn to_arc(self) -> GSInfo {
|
pub fn to_arc(self) -> GSInfo {
|
||||||
Arc::new(self)
|
Arc::new(self)
|
||||||
@ -42,7 +94,7 @@ impl Default for GlobalScriptInfo {
|
|||||||
enum_variants: Self::default_enum_variants(),
|
enum_variants: Self::default_enum_variants(),
|
||||||
custom_type_names: HashMap::new(),
|
custom_type_names: HashMap::new(),
|
||||||
custom_types: vec![],
|
custom_types: vec![],
|
||||||
#[cfg(debug_assertions)]
|
formatter: Default::default(),
|
||||||
log: Logger::new(),
|
log: Logger::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,20 +109,21 @@ impl GlobalScriptInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Logger {
|
pub struct Logger {
|
||||||
logs: Arc<Mutex<Vec<LogMsg>>>,
|
logs: Arc<Mutex<Vec<LogMsg>>>,
|
||||||
|
|
||||||
|
pub after_parse: LogKind,
|
||||||
|
|
||||||
pub vdata_clone: LogKind,
|
pub vdata_clone: LogKind,
|
||||||
pub vtype_fits_in: LogKind,
|
pub vtype_fits_in: LogKind,
|
||||||
pub vsingletype_fits_in: LogKind,
|
pub vsingletype_fits_in: LogKind,
|
||||||
}
|
}
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
impl Logger {
|
impl Logger {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
logs: Arc::new(Mutex::new(vec![])),
|
logs: Arc::new(Mutex::new(vec![])),
|
||||||
|
after_parse: Default::default(),
|
||||||
vdata_clone: Default::default(),
|
vdata_clone: Default::default(),
|
||||||
vtype_fits_in: Default::default(),
|
vtype_fits_in: Default::default(),
|
||||||
vsingletype_fits_in: Default::default(),
|
vsingletype_fits_in: Default::default(),
|
||||||
@ -78,17 +131,17 @@ impl Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum LogMsg {
|
pub enum LogMsg {
|
||||||
|
AfterParse(String),
|
||||||
VDataClone(Option<String>, VDataEnum, usize, usize),
|
VDataClone(Option<String>, VDataEnum, usize, usize),
|
||||||
VTypeFitsIn(VType, VType, Vec<VSingleType>),
|
VTypeFitsIn(VType, VType, Vec<VSingleType>),
|
||||||
VSingleTypeFitsIn(VSingleType, VSingleType, bool),
|
VSingleTypeFitsIn(VSingleType, VSingleType, bool),
|
||||||
}
|
}
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
impl Logger {
|
impl Logger {
|
||||||
pub fn log(&self, msg: LogMsg) {
|
pub fn log(&self, msg: LogMsg) {
|
||||||
let kind = match msg {
|
let kind = match msg {
|
||||||
|
LogMsg::AfterParse(..) => &self.after_parse,
|
||||||
LogMsg::VDataClone(..) => &self.vdata_clone,
|
LogMsg::VDataClone(..) => &self.vdata_clone,
|
||||||
LogMsg::VTypeFitsIn(..) => &self.vtype_fits_in,
|
LogMsg::VTypeFitsIn(..) => &self.vtype_fits_in,
|
||||||
LogMsg::VSingleTypeFitsIn(..) => &self.vsingletype_fits_in,
|
LogMsg::VSingleTypeFitsIn(..) => &self.vsingletype_fits_in,
|
||||||
@ -103,14 +156,16 @@ impl Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
impl Display for LogMsg {
|
impl Display for LogMsg {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
Self::AfterParse(code) => {
|
||||||
|
write!(f, "AfterParse :: {code}")
|
||||||
|
}
|
||||||
Self::VDataClone(varname, data, src_addr, new_addr) => {
|
Self::VDataClone(varname, data, src_addr, new_addr) => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"VDataClone :: {data} ({}{src_addr} -> {new_addr})",
|
"VDataClone ::::\n{data} ({}{src_addr} -> {new_addr})",
|
||||||
if let Some(v) = varname {
|
if let Some(v) = varname {
|
||||||
format!("{v} | ")
|
format!("{v} | ")
|
||||||
} else {
|
} else {
|
||||||
@ -126,13 +181,11 @@ impl Display for LogMsg {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct LogKind {
|
pub struct LogKind {
|
||||||
pub stderr: bool,
|
pub stderr: bool,
|
||||||
pub log: bool,
|
pub log: bool,
|
||||||
}
|
}
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
impl LogKind {
|
impl LogKind {
|
||||||
pub fn log(&self) -> bool {
|
pub fn log(&self) -> bool {
|
||||||
self.stderr || self.log
|
self.stderr || self.log
|
||||||
|
@ -2,6 +2,7 @@ pub mod builtins;
|
|||||||
pub mod code_macro;
|
pub mod code_macro;
|
||||||
pub mod code_parsed;
|
pub mod code_parsed;
|
||||||
pub mod code_runnable;
|
pub mod code_runnable;
|
||||||
|
pub mod fmtgs;
|
||||||
pub mod global_info;
|
pub mod global_info;
|
||||||
pub mod to_runnable;
|
pub mod to_runnable;
|
||||||
pub mod val_data;
|
pub mod val_data;
|
||||||
|
@ -19,6 +19,7 @@ use super::{
|
|||||||
code_macro::Macro,
|
code_macro::Macro,
|
||||||
code_parsed::{SBlock, SFunction, SStatement, SStatementEnum},
|
code_parsed::{SBlock, SFunction, SStatement, SStatementEnum},
|
||||||
code_runnable::{RBlock, RFunction, RScript, RStatement, RStatementEnum},
|
code_runnable::{RBlock, RFunction, RScript, RStatement, RStatementEnum},
|
||||||
|
fmtgs::FormatGs,
|
||||||
global_info::GSInfo,
|
global_info::GSInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,18 +52,20 @@ impl Debug for ToRunnableError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO:
|
// TODO:
|
||||||
// - Don't use {} to format, use .fmtgs(f, info) instead!
|
// - Don't use {} to format, use .fmtgs(f, info, form, file) instead!
|
||||||
// - Show location in code where the error was found
|
// - Show location in code where the error was found
|
||||||
impl Display for ToRunnableError {
|
impl Display for ToRunnableError {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
self.fmtgs(f, None)
|
self.fmtgs(f, None, &mut super::fmtgs::FormatInfo::default(), None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ToRunnableError {
|
impl FormatGs for ToRunnableError {
|
||||||
pub fn fmtgs(
|
fn fmtgs(
|
||||||
&self,
|
&self,
|
||||||
f: &mut std::fmt::Formatter,
|
f: &mut std::fmt::Formatter,
|
||||||
info: Option<&GlobalScriptInfo>,
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut super::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
) -> std::fmt::Result {
|
) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::MainWrongInput => write!(
|
Self::MainWrongInput => write!(
|
||||||
@ -75,9 +78,9 @@ impl ToRunnableError {
|
|||||||
Self::CannotDeclareVariableWithDereference(v) => write!(f, "Cannot declare a variable and dereference it (variable '{v}')."),
|
Self::CannotDeclareVariableWithDereference(v) => write!(f, "Cannot declare a variable and dereference it (variable '{v}')."),
|
||||||
Self::CannotDereferenceTypeNTimes(og_type, derefs_wanted, last_valid_type) => {
|
Self::CannotDereferenceTypeNTimes(og_type, derefs_wanted, last_valid_type) => {
|
||||||
write!(f, "Cannot dereference type ")?;
|
write!(f, "Cannot dereference type ")?;
|
||||||
og_type.fmtgs(f, info)?;
|
og_type.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " {derefs_wanted} times (stopped at ")?;
|
write!(f, " {derefs_wanted} times (stopped at ")?;
|
||||||
last_valid_type.fmtgs(f, info);
|
last_valid_type.fmtgs(f, info, form, file);
|
||||||
write!(f, ")")?;
|
write!(f, ")")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
@ -89,28 +92,28 @@ impl ToRunnableError {
|
|||||||
problematic,
|
problematic,
|
||||||
} => {
|
} => {
|
||||||
write!(f, "Invalid type: Expected ")?;
|
write!(f, "Invalid type: Expected ")?;
|
||||||
expected.fmtgs(f, info)?;
|
expected.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " but found ")?;
|
write!(f, " but found ")?;
|
||||||
found.fmtgs(f, info)?;
|
found.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ", which includes ")?;
|
write!(f, ", which includes ")?;
|
||||||
problematic.fmtgs(f, info)?;
|
problematic.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " which is not covered.")?;
|
write!(f, " which is not covered.")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Self::CaseForceButTypeNotCovered(v) => {
|
Self::CaseForceButTypeNotCovered(v) => {
|
||||||
write!(f, "Switch! statement, but not all types covered. Types to cover: ")?;
|
write!(f, "Switch! statement, but not all types covered. Types to cover: ")?;
|
||||||
v.fmtgs(f, info)?;
|
v.fmtgs(f, info, form, file)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Self::MatchConditionInvalidReturn(v) => {
|
Self::MatchConditionInvalidReturn(v) => {
|
||||||
write!(f, "match statement condition returned ")?;
|
write!(f, "match statement condition returned ")?;
|
||||||
v.fmtgs(f, info)?;
|
v.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ", which is not necessarily a tuple of size 0 to 1.")?;
|
write!(f, ", which is not necessarily a tuple of size 0 to 1.")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Self::NotIndexableFixed(t, i) => {
|
Self::NotIndexableFixed(t, i) => {
|
||||||
write!(f, "Cannot use fixed-index {i} on type ")?;
|
write!(f, "Cannot use fixed-index {i} on type ")?;
|
||||||
t.fmtgs(f, info)?;
|
t.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ".")?;
|
write!(f, ".")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -118,7 +121,7 @@ impl ToRunnableError {
|
|||||||
write!(f, "Wrong arguments for builtin function \"{}\":", builtin_name)?;
|
write!(f, "Wrong arguments for builtin function \"{}\":", builtin_name)?;
|
||||||
for arg in args {
|
for arg in args {
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
arg.fmtgs(f, info)?;
|
arg.fmtgs(f, info, form, file)?;
|
||||||
}
|
}
|
||||||
write!(f, ".")
|
write!(f, ".")
|
||||||
}
|
}
|
||||||
@ -126,15 +129,15 @@ impl ToRunnableError {
|
|||||||
write!(f, "Wrong arguments for library function {}:", name)?;
|
write!(f, "Wrong arguments for library function {}:", name)?;
|
||||||
for arg in args {
|
for arg in args {
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
arg.fmtgs(f, info)?;
|
arg.fmtgs(f, info, form, file)?;
|
||||||
}
|
}
|
||||||
write!(f, ".")
|
write!(f, ".")
|
||||||
}
|
}
|
||||||
Self::CannotAssignTo(val, target) => {
|
Self::CannotAssignTo(val, target) => {
|
||||||
write!(f, "Cannot assign type ")?;
|
write!(f, "Cannot assign type ")?;
|
||||||
val.fmtgs(f, info)?;
|
val.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " to ")?;
|
write!(f, " to ")?;
|
||||||
target.fmtgs(f, info)?;
|
target.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ".")?;
|
write!(f, ".")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
@ -143,11 +146,11 @@ impl ToRunnableError {
|
|||||||
}
|
}
|
||||||
Self::StatementRequiresOutputTypeToBeAButItActuallyOutputsBWhichDoesNotFitInA(required, real, problematic) => {
|
Self::StatementRequiresOutputTypeToBeAButItActuallyOutputsBWhichDoesNotFitInA(required, real, problematic) => {
|
||||||
write!(f, "the statement requires its output type to be ")?;
|
write!(f, "the statement requires its output type to be ")?;
|
||||||
required.fmtgs(f, info)?;
|
required.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ", but its real output type is ")?;
|
write!(f, ", but its real output type is ")?;
|
||||||
real.fmtgs(f, info)?;
|
real.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ", which doesn't fit in the required type because of the problematic types ")?;
|
write!(f, ", which doesn't fit in the required type because of the problematic types ")?;
|
||||||
problematic.fmtgs(f, info)?;
|
problematic.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ".")?;
|
write!(f, ".")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,14 @@ use std::{
|
|||||||
sync::{Arc, Mutex, MutexGuard},
|
sync::{Arc, Mutex, MutexGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::global_info::LogMsg;
|
||||||
use super::{
|
use super::{
|
||||||
code_runnable::RFunction,
|
code_runnable::RFunction,
|
||||||
|
fmtgs::FormatGs,
|
||||||
global_info::{GSInfo, GlobalScriptInfo},
|
global_info::{GSInfo, GlobalScriptInfo},
|
||||||
val_type::{VSingleType, VType},
|
val_type::{VSingleType, VType},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
use super::global_info::LogMsg;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum VDataEnum {
|
pub enum VDataEnum {
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
@ -117,11 +116,13 @@ impl VData {
|
|||||||
// *self doesn't modify the ::Data, it instead points the value that wraps it to a new ::Data, leaving the old one as it was.
|
// *self doesn't modify the ::Data, it instead points the value that wraps it to a new ::Data, leaving the old one as it was.
|
||||||
// for proof: data is untouched, only the new_data is ever modified.
|
// for proof: data is untouched, only the new_data is ever modified.
|
||||||
let new_vdata = VDataInner::Data(0, new_data).to();
|
let new_vdata = VDataInner::Data(0, new_data).to();
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
if info.log.vdata_clone.log() {
|
if info.log.vdata_clone.log() {
|
||||||
drop(lock);
|
drop(lock);
|
||||||
info.log.log(LogMsg::VDataClone(
|
info.log.log(LogMsg::VDataClone(
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
self.1.clone(),
|
self.1.clone(),
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
None,
|
||||||
self.inner_cloned(),
|
self.inner_cloned(),
|
||||||
Arc::as_ptr(&self.0) as usize,
|
Arc::as_ptr(&self.0) as usize,
|
||||||
Arc::as_ptr(&new_vdata.0) as usize,
|
Arc::as_ptr(&new_vdata.0) as usize,
|
||||||
@ -187,9 +188,15 @@ impl Clone for VData {
|
|||||||
self.clone_data()
|
self.clone_data()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl VData {
|
impl FormatGs for VData {
|
||||||
pub fn fmtgs(&self, f: &mut Formatter<'_>, info: Option<&GlobalScriptInfo>) -> fmt::Result {
|
fn fmtgs(
|
||||||
self.operate_on_data_immut(|v| v.fmtgs(f, info))
|
&self,
|
||||||
|
f: &mut Formatter,
|
||||||
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut super::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
|
self.operate_on_data_immut(|v| v.fmtgs(f, info, form, file))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Debug for VData {
|
impl Debug for VData {
|
||||||
@ -476,7 +483,12 @@ pub mod thread {
|
|||||||
pub struct VDataWInfo(VData, GSInfo);
|
pub struct VDataWInfo(VData, GSInfo);
|
||||||
impl Display for VDataWInfo {
|
impl Display for VDataWInfo {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
self.0.fmtgs(f, Some(&self.1))
|
self.0.fmtgs(
|
||||||
|
f,
|
||||||
|
Some(&self.1),
|
||||||
|
&mut super::fmtgs::FormatInfo::default(),
|
||||||
|
None,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl VData {
|
impl VData {
|
||||||
@ -485,39 +497,51 @@ impl VData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VDataEnum {
|
impl FormatGs for VDataEnum {
|
||||||
pub fn fmtgs(&self, f: &mut Formatter, info: Option<&GlobalScriptInfo>) -> fmt::Result {
|
fn fmtgs(
|
||||||
|
&self,
|
||||||
|
f: &mut Formatter,
|
||||||
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut super::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::Bool(true) => write!(f, "true"),
|
Self::Bool(true) => write!(f, "true"),
|
||||||
Self::Bool(false) => write!(f, "false"),
|
Self::Bool(false) => write!(f, "false"),
|
||||||
Self::Int(v) => write!(f, "{v}"),
|
Self::Int(v) => write!(f, "{v}"),
|
||||||
Self::Float(v) => write!(f, "{v}"),
|
Self::Float(v) => write!(f, "{v}"),
|
||||||
Self::String(v) => write!(f, "\"{v}\""),
|
Self::String(v) => write!(
|
||||||
|
f,
|
||||||
|
"{}{}{}",
|
||||||
|
form.value_string_quotes(info, "\"".to_owned()),
|
||||||
|
form.value_string_content(info, v.to_owned()),
|
||||||
|
form.value_string_quotes(info, "\"".to_owned())
|
||||||
|
),
|
||||||
Self::Tuple(v) => {
|
Self::Tuple(v) => {
|
||||||
write!(f, "[")?;
|
write!(f, "[")?;
|
||||||
for (i, v) in v.iter().enumerate() {
|
for (i, v) in v.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
}
|
}
|
||||||
v.fmtgs(f, info)?;
|
v.fmtgs(f, info, form, file)?;
|
||||||
}
|
}
|
||||||
write!(f, "]")
|
write!(f, "]")
|
||||||
}
|
}
|
||||||
Self::List(_t, v) => {
|
Self::List(_t, v) => {
|
||||||
write!(f, "[")?;
|
write!(f, "[")?;
|
||||||
for (i, v) in v.iter().enumerate() {
|
for (i, v) in v.iter().enumerate() {
|
||||||
v.fmtgs(f, info)?;
|
v.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
}
|
}
|
||||||
write!(f, "...]")
|
write!(f, "...]")
|
||||||
}
|
}
|
||||||
Self::Function(func) => {
|
Self::Function(func) => {
|
||||||
VSingleType::Function(func.input_output_map.clone()).fmtgs(f, info)
|
VSingleType::Function(func.input_output_map.clone()).fmtgs(f, info, form, file)
|
||||||
}
|
}
|
||||||
Self::Thread(..) => write!(f, "[TODO] THREAD"),
|
Self::Thread(..) => write!(f, "[TODO] THREAD"),
|
||||||
Self::Reference(inner) => {
|
Self::Reference(inner) => {
|
||||||
write!(f, "&")?;
|
write!(f, "&")?;
|
||||||
inner.fmtgs(f, info)
|
inner.fmtgs(f, info, form, file)
|
||||||
}
|
}
|
||||||
Self::EnumVariant(variant, inner) => {
|
Self::EnumVariant(variant, inner) => {
|
||||||
if let Some(name) = if let Some(info) = info {
|
if let Some(name) = if let Some(info) = info {
|
||||||
@ -535,13 +559,13 @@ impl VDataEnum {
|
|||||||
} else {
|
} else {
|
||||||
write!(f, "{variant}: ")?;
|
write!(f, "{variant}: ")?;
|
||||||
}
|
}
|
||||||
inner.fmtgs(f, info)
|
inner.fmtgs(f, info, form, file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Display for VDataEnum {
|
impl Display for VDataEnum {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
self.fmtgs(f, None)
|
self.fmtgs(f, None, &mut super::fmtgs::FormatInfo::default(), None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,11 @@ use std::{
|
|||||||
ops::BitOr,
|
ops::BitOr,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::global_info::{self, GSInfo, GlobalScriptInfo};
|
use super::{
|
||||||
|
fmtgs::FormatGs,
|
||||||
|
global_info::{self, GSInfo, GlobalScriptInfo},
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
use super::global_info::LogMsg;
|
use super::global_info::LogMsg;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
@ -161,7 +163,6 @@ impl VType {
|
|||||||
no.push(t.clone())
|
no.push(t.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
if info.log.vtype_fits_in.log() {
|
if info.log.vtype_fits_in.log() {
|
||||||
info.log
|
info.log
|
||||||
.log(LogMsg::VTypeFitsIn(self.clone(), rhs.clone(), no.clone()))
|
.log(LogMsg::VTypeFitsIn(self.clone(), rhs.clone(), no.clone()))
|
||||||
@ -359,7 +360,6 @@ impl VSingleType {
|
|||||||
(Self::Thread(a), Self::Thread(b)) => a.fits_in(b, info).is_empty(),
|
(Self::Thread(a), Self::Thread(b)) => a.fits_in(b, info).is_empty(),
|
||||||
(Self::Thread(..), _) => false,
|
(Self::Thread(..), _) => false,
|
||||||
};
|
};
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
if info.log.vsingletype_fits_in.log() {
|
if info.log.vsingletype_fits_in.log() {
|
||||||
info.log
|
info.log
|
||||||
.log(LogMsg::VSingleTypeFitsIn(self.clone(), rhs.clone(), o));
|
.log(LogMsg::VSingleTypeFitsIn(self.clone(), rhs.clone(), o));
|
||||||
@ -393,7 +393,12 @@ impl Into<VType> for VSingleType {
|
|||||||
pub struct VTypeWInfo(VType, GSInfo);
|
pub struct VTypeWInfo(VType, GSInfo);
|
||||||
impl Display for VTypeWInfo {
|
impl Display for VTypeWInfo {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
self.0.fmtgs(f, Some(&self.1))
|
self.0.fmtgs(
|
||||||
|
f,
|
||||||
|
Some(&self.1),
|
||||||
|
&mut super::fmtgs::FormatInfo::default(),
|
||||||
|
None,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl VType {
|
impl VType {
|
||||||
@ -402,8 +407,14 @@ impl VType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VSingleType {
|
impl FormatGs for VSingleType {
|
||||||
pub fn fmtgs(&self, f: &mut Formatter, info: Option<&GlobalScriptInfo>) -> fmt::Result {
|
fn fmtgs(
|
||||||
|
&self,
|
||||||
|
f: &mut Formatter,
|
||||||
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut super::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::Bool => write!(f, "bool"),
|
Self::Bool => write!(f, "bool"),
|
||||||
Self::Int => write!(f, "int"),
|
Self::Int => write!(f, "int"),
|
||||||
@ -415,13 +426,13 @@ impl VSingleType {
|
|||||||
if i > 0 {
|
if i > 0 {
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
}
|
}
|
||||||
v.fmtgs(f, info)?;
|
v.fmtgs(f, info, form, file)?;
|
||||||
}
|
}
|
||||||
write!(f, "]")
|
write!(f, "]")
|
||||||
}
|
}
|
||||||
Self::List(v) => {
|
Self::List(v) => {
|
||||||
write!(f, "[")?;
|
write!(f, "[")?;
|
||||||
v.fmtgs(f, info)?;
|
v.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " ...]")
|
write!(f, " ...]")
|
||||||
}
|
}
|
||||||
Self::Function(func) => {
|
Self::Function(func) => {
|
||||||
@ -429,22 +440,22 @@ impl VSingleType {
|
|||||||
for (inputs, output) in func {
|
for (inputs, output) in func {
|
||||||
write!(f, "(")?;
|
write!(f, "(")?;
|
||||||
for i in inputs {
|
for i in inputs {
|
||||||
i.fmtgs(f, info)?;
|
i.fmtgs(f, info, form, file)?;
|
||||||
write!(f, " ");
|
write!(f, " ");
|
||||||
}
|
}
|
||||||
output.fmtgs(f, info)?;
|
output.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ")")?;
|
write!(f, ")")?;
|
||||||
}
|
}
|
||||||
write!(f, ")")
|
write!(f, ")")
|
||||||
}
|
}
|
||||||
Self::Thread(out) => {
|
Self::Thread(out) => {
|
||||||
write!(f, "thread(")?;
|
write!(f, "thread(")?;
|
||||||
out.fmtgs(f, info)?;
|
out.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ")")
|
write!(f, ")")
|
||||||
}
|
}
|
||||||
Self::Reference(inner) => {
|
Self::Reference(inner) => {
|
||||||
write!(f, "&")?;
|
write!(f, "&")?;
|
||||||
inner.fmtgs(f, info)
|
inner.fmtgs(f, info, form, file)
|
||||||
}
|
}
|
||||||
Self::EnumVariant(variant, inner) => {
|
Self::EnumVariant(variant, inner) => {
|
||||||
if let Some(name) = if let Some(info) = info {
|
if let Some(name) = if let Some(info) = info {
|
||||||
@ -462,12 +473,12 @@ impl VSingleType {
|
|||||||
} else {
|
} else {
|
||||||
write!(f, "{variant}(")?;
|
write!(f, "{variant}(")?;
|
||||||
}
|
}
|
||||||
inner.fmtgs(f, info)?;
|
inner.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ")")
|
write!(f, ")")
|
||||||
}
|
}
|
||||||
Self::EnumVariantS(name, inner) => {
|
Self::EnumVariantS(name, inner) => {
|
||||||
write!(f, "{name}(")?;
|
write!(f, "{name}(")?;
|
||||||
inner.fmtgs(f, info)?;
|
inner.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ")")
|
write!(f, ")")
|
||||||
}
|
}
|
||||||
Self::CustomType(t) => {
|
Self::CustomType(t) => {
|
||||||
@ -510,23 +521,29 @@ impl VSingleType {
|
|||||||
}
|
}
|
||||||
impl Display for VSingleType {
|
impl Display for VSingleType {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
self.fmtgs(f, None)
|
self.fmtgs(f, None, &mut super::fmtgs::FormatInfo::default(), None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VType {
|
impl FormatGs for VType {
|
||||||
pub fn fmtgs(&self, f: &mut Formatter, info: Option<&GlobalScriptInfo>) -> fmt::Result {
|
fn fmtgs(
|
||||||
|
&self,
|
||||||
|
f: &mut Formatter,
|
||||||
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut super::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
for (i, t) in self.types.iter().enumerate() {
|
for (i, t) in self.types.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
write!(f, "/")?;
|
write!(f, "/")?;
|
||||||
}
|
}
|
||||||
t.fmtgs(f, info)?;
|
t.fmtgs(f, info, form, file)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Display for VType {
|
impl Display for VType {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
self.fmtgs(f, None)
|
self.fmtgs(f, None, &mut super::fmtgs::FormatInfo::default(), None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,13 @@
|
|||||||
|
|
||||||
use std::{fs, time::Instant};
|
use std::{fs, time::Instant};
|
||||||
|
|
||||||
|
use lang::global_info::ColorFormatMode;
|
||||||
use lang::global_info::GlobalScriptInfo;
|
use lang::global_info::GlobalScriptInfo;
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
use lang::global_info::LogKind;
|
use lang::global_info::LogKind;
|
||||||
use notify::Watcher as FsWatcher;
|
use notify::Watcher as FsWatcher;
|
||||||
|
|
||||||
|
use crate::lang::fmtgs::FormatGs;
|
||||||
|
|
||||||
mod interactive_mode;
|
mod interactive_mode;
|
||||||
mod lang;
|
mod lang;
|
||||||
mod libs;
|
mod libs;
|
||||||
@ -26,6 +28,7 @@ fn main() {
|
|||||||
fn normal_main() {
|
fn normal_main() {
|
||||||
let args: Vec<_> = std::env::args().skip(1).collect();
|
let args: Vec<_> = std::env::args().skip(1).collect();
|
||||||
let mut info = GlobalScriptInfo::default();
|
let mut info = GlobalScriptInfo::default();
|
||||||
|
let mut run = true;
|
||||||
let mut args_to_skip = 2;
|
let mut args_to_skip = 2;
|
||||||
let mut file = match args.len() {
|
let mut file = match args.len() {
|
||||||
0 => {
|
0 => {
|
||||||
@ -52,6 +55,10 @@ fn normal_main() {
|
|||||||
match ch {
|
match ch {
|
||||||
'e' => execute = true,
|
'e' => execute = true,
|
||||||
'v' => verbose = true,
|
'v' => verbose = true,
|
||||||
|
'f' => {
|
||||||
|
run = false;
|
||||||
|
info.log.after_parse.stderr = true;
|
||||||
|
}
|
||||||
'V' => print_version = true,
|
'V' => print_version = true,
|
||||||
'i' => interactive += 1,
|
'i' => interactive += 1,
|
||||||
't' => teachme = true,
|
't' => teachme = true,
|
||||||
@ -75,6 +82,11 @@ fn normal_main() {
|
|||||||
verbose_args.push(ch);
|
verbose_args.push(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
'f' => match ch {
|
||||||
|
'c' => info.formatter.mode = ColorFormatMode::Colorize,
|
||||||
|
'C' => info.formatter.mode = ColorFormatMode::Plain,
|
||||||
|
_ => eprintln!("Ignoring f+{ch}. (unknown adv char)"),
|
||||||
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -97,9 +109,6 @@ fn normal_main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if verbose {
|
if verbose {
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
eprintln!("WARN: Verbose (-v) only works in debug builds!");
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
if verbose_args.is_empty() {
|
if verbose_args.is_empty() {
|
||||||
fn f() -> LogKind {
|
fn f() -> LogKind {
|
||||||
LogKind {
|
LogKind {
|
||||||
@ -187,12 +196,9 @@ fn normal_main() {
|
|||||||
};
|
};
|
||||||
match parsing::parse::parse_custom_info(&mut file, info) {
|
match parsing::parse::parse_custom_info(&mut file, info) {
|
||||||
Ok(script) => {
|
Ok(script) => {
|
||||||
println!(" - - - - -");
|
if run {
|
||||||
let start = Instant::now();
|
script.run(std::env::args().skip(args_to_skip).collect());
|
||||||
let out = script.run(std::env::args().skip(args_to_skip).collect());
|
}
|
||||||
let elapsed = start.elapsed();
|
|
||||||
println!(" - - - - -");
|
|
||||||
println!("Output ({}s)\n{out}", elapsed.as_secs_f64());
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Couldn't compile:\n{}", e.with_file(&file));
|
println!("Couldn't compile:\n{}", e.with_file(&file));
|
||||||
|
@ -5,6 +5,7 @@ use crate::{
|
|||||||
code_macro::MacroError,
|
code_macro::MacroError,
|
||||||
code_parsed::*,
|
code_parsed::*,
|
||||||
code_runnable::RScript,
|
code_runnable::RScript,
|
||||||
|
fmtgs::{FormatGs, FormatWithGs},
|
||||||
global_info::{GSInfo, GlobalScriptInfo},
|
global_info::{GSInfo, GlobalScriptInfo},
|
||||||
to_runnable::{self, ToRunnableError},
|
to_runnable::{self, ToRunnableError},
|
||||||
val_data::VDataEnum,
|
val_data::VDataEnum,
|
||||||
@ -13,6 +14,8 @@ use crate::{
|
|||||||
libs,
|
libs,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::lang::global_info::LogMsg;
|
||||||
|
|
||||||
use super::file::File;
|
use super::file::File;
|
||||||
|
|
||||||
pub enum ScriptError {
|
pub enum ScriptError {
|
||||||
@ -51,59 +54,30 @@ impl std::fmt::Display for ScriptError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub struct ScriptErrorWithFile<'a>(&'a ScriptError, &'a File);
|
impl FormatGs for ScriptError {
|
||||||
pub struct ScriptErrorWithInfo<'a>(&'a ScriptError, &'a GlobalScriptInfo);
|
fn fmtgs(
|
||||||
pub struct ScriptErrorWithFileAndInfo<'a>(&'a ScriptError, &'a File, &'a GlobalScriptInfo);
|
|
||||||
impl<'a> ScriptError {
|
|
||||||
pub fn with_file(&'a self, file: &'a File) -> ScriptErrorWithFile {
|
|
||||||
ScriptErrorWithFile(self, file)
|
|
||||||
}
|
|
||||||
pub fn with_gsinfo(&'a self, info: &'a GlobalScriptInfo) -> ScriptErrorWithInfo {
|
|
||||||
ScriptErrorWithInfo(self, info)
|
|
||||||
}
|
|
||||||
pub fn with_file_and_gsinfo(
|
|
||||||
&'a self,
|
|
||||||
file: &'a File,
|
|
||||||
info: &'a GlobalScriptInfo,
|
|
||||||
) -> ScriptErrorWithFileAndInfo {
|
|
||||||
ScriptErrorWithFileAndInfo(self, file, info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> std::fmt::Display for ScriptErrorWithFile<'a> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
self.0.fmt_custom(f, Some(self.1), None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> std::fmt::Display for ScriptErrorWithInfo<'a> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
self.0.fmt_custom(f, None, Some(self.1))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> std::fmt::Display for ScriptErrorWithFileAndInfo<'a> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
self.0.fmt_custom(f, Some(self.1), Some(self.2))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ScriptError {
|
|
||||||
fn fmt_custom(
|
|
||||||
&self,
|
&self,
|
||||||
f: &mut std::fmt::Formatter<'_>,
|
f: &mut std::fmt::Formatter,
|
||||||
file: Option<&File>,
|
|
||||||
info: Option<&GlobalScriptInfo>,
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut crate::lang::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
) -> std::fmt::Result {
|
) -> std::fmt::Result {
|
||||||
match &self {
|
match &self {
|
||||||
ScriptError::CannotFindPathForLibrary(e) => write!(f, "{e}"),
|
ScriptError::CannotFindPathForLibrary(e) => write!(f, "{e}"),
|
||||||
ScriptError::ParseError(e) => {
|
ScriptError::ParseError(e) => {
|
||||||
write!(f, "failed while parsing: ")?;
|
write!(f, "failed while parsing: ")?;
|
||||||
e.fmt_custom(f, file)?;
|
e.fmtgs(f, info, form, file)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
ScriptError::UnableToLoadLibrary(e) => write!(f, "{e}"),
|
ScriptError::UnableToLoadLibrary(e) => write!(f, "{e}"),
|
||||||
ScriptError::ToRunnableError(e) => {
|
ScriptError::ToRunnableError(e) => {
|
||||||
write!(f, "failed to compile: ")?;
|
write!(f, "failed to compile: ")?;
|
||||||
e.fmtgs(f, info);
|
e.fmtgs(
|
||||||
Ok(())
|
f,
|
||||||
|
info,
|
||||||
|
&mut crate::lang::fmtgs::FormatInfo::default(),
|
||||||
|
file,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,14 +97,25 @@ impl From<(ScriptError, GSInfo)> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Debug for Error {
|
impl FormatGs for Error {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmtgs(
|
||||||
write!(f, "{}", self.err.with_gsinfo(&self.ginfo))
|
&self,
|
||||||
|
f: &mut std::fmt::Formatter,
|
||||||
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut crate::lang::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
|
self.err.fmtgs(f, Some(&self.ginfo), form, file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Error {
|
impl Debug for Error {
|
||||||
pub fn with_file<'a>(&'a self, file: &'a File) -> ScriptErrorWithFileAndInfo<'a> {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
self.err.with_file_and_gsinfo(file, self.ginfo.as_ref())
|
self.err.fmtgs(
|
||||||
|
f,
|
||||||
|
Some(self.ginfo.as_ref()),
|
||||||
|
&mut crate::lang::fmtgs::FormatInfo::default(),
|
||||||
|
None,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,19 +125,16 @@ pub fn parse(file: &mut File) -> Result<RScript, Error> {
|
|||||||
}
|
}
|
||||||
/// like parse, but GlobalInfo can be something other than Default::default().
|
/// like parse, but GlobalInfo can be something other than Default::default().
|
||||||
pub fn parse_custom_info(file: &mut File, mut ginfo: GlobalScriptInfo) -> Result<RScript, Error> {
|
pub fn parse_custom_info(file: &mut File, mut ginfo: GlobalScriptInfo) -> Result<RScript, Error> {
|
||||||
let libs = match parse_step_lib_paths(file) {
|
let libs = match parse_step_lib_paths(file, &ginfo) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => return Err((e.into(), ginfo.to_arc()).into()),
|
Err(e) => return Err((e.into(), ginfo.to_arc()).into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let func = match parse_step_interpret(file) {
|
let func = match parse_step_interpret(file, &ginfo) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => return Err((e.into(), ginfo.to_arc()).into()),
|
Err(e) => return Err((e.into(), ginfo.to_arc()).into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
eprintln!("{func:#?}");
|
|
||||||
|
|
||||||
ginfo.libs = match parse_step_libs_load(libs, &mut ginfo) {
|
ginfo.libs = match parse_step_libs_load(libs, &mut ginfo) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => return Err((e.into(), ginfo.to_arc()).into()),
|
Err(e) => return Err((e.into(), ginfo.to_arc()).into()),
|
||||||
@ -174,7 +156,10 @@ impl std::fmt::Display for CannotFindPathForLibrary {
|
|||||||
write!(f, "Couldn't find a path for the library with the path '{}'. Maybe set the MERS_LIB_DIR env variable?", self.0)
|
write!(f, "Couldn't find a path for the library with the path '{}'. Maybe set the MERS_LIB_DIR env variable?", self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn parse_step_lib_paths(file: &mut File) -> Result<Vec<Command>, CannotFindPathForLibrary> {
|
pub fn parse_step_lib_paths(
|
||||||
|
file: &mut File,
|
||||||
|
ginfo: &GlobalScriptInfo,
|
||||||
|
) -> Result<Vec<Command>, CannotFindPathForLibrary> {
|
||||||
let mut libs = vec![];
|
let mut libs = vec![];
|
||||||
loop {
|
loop {
|
||||||
file.skip_whitespaces();
|
file.skip_whitespaces();
|
||||||
@ -198,14 +183,23 @@ pub fn parse_step_lib_paths(file: &mut File) -> Result<Vec<Command>, CannotFindP
|
|||||||
Ok(libs)
|
Ok(libs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_step_interpret(file: &mut File) -> Result<SFunction, ParseError> {
|
pub fn parse_step_interpret(
|
||||||
Ok(SFunction::new(
|
file: &mut File,
|
||||||
|
ginfo: &GlobalScriptInfo,
|
||||||
|
) -> Result<SFunction, ParseError> {
|
||||||
|
let o = SFunction::new(
|
||||||
vec![(
|
vec![(
|
||||||
"args".to_string(),
|
"args".to_string(),
|
||||||
VSingleType::List(VSingleType::String.into()).to(),
|
VSingleType::List(VSingleType::String.into()).to(),
|
||||||
)],
|
)],
|
||||||
parse_block_advanced(file, Some(false), true, true, false)?,
|
parse_block_advanced(file, Some(false), true, true, false)?,
|
||||||
))
|
);
|
||||||
|
if ginfo.log.after_parse.log() {
|
||||||
|
ginfo.log.log(LogMsg::AfterParse(
|
||||||
|
o.with_info_and_file(ginfo, &file).to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -242,17 +236,6 @@ pub fn parse_step_compile(
|
|||||||
to_runnable::to_runnable(main_func, ginfo)
|
to_runnable::to_runnable(main_func, ginfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ParseErrorWithFile<'a>(&'a ParseError, &'a File);
|
|
||||||
impl<'a> ParseError {
|
|
||||||
pub fn with_file(&'a self, file: &'a File) -> ParseErrorWithFile {
|
|
||||||
ParseErrorWithFile(self, file)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> std::fmt::Display for ParseErrorWithFile<'a> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
self.0.fmt_custom(f, Some(self.1))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub struct ParseError {
|
pub struct ParseError {
|
||||||
err: ParseErrors,
|
err: ParseErrors,
|
||||||
// the location of the error
|
// the location of the error
|
||||||
@ -264,13 +247,15 @@ pub struct ParseError {
|
|||||||
)>,
|
)>,
|
||||||
info: Option<GlobalScriptInfo>,
|
info: Option<GlobalScriptInfo>,
|
||||||
}
|
}
|
||||||
impl ParseError {
|
impl FormatGs for ParseError {
|
||||||
pub fn fmt_custom(
|
fn fmtgs(
|
||||||
&self,
|
&self,
|
||||||
f: &mut std::fmt::Formatter<'_>,
|
f: &mut std::fmt::Formatter,
|
||||||
file: Option<&super::file::File>,
|
info: Option<&GlobalScriptInfo>,
|
||||||
|
form: &mut crate::lang::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
) -> std::fmt::Result {
|
) -> std::fmt::Result {
|
||||||
self.err.fmtgs(f, self.info.as_ref(), file)?;
|
self.err.fmtgs(f, self.info.as_ref(), form, file)?;
|
||||||
writeln!(f);
|
writeln!(f);
|
||||||
if let Some(location_end) = self.location_end {
|
if let Some(location_end) = self.location_end {
|
||||||
writeln!(f, " from {} to {}", self.location, location_end)?;
|
writeln!(f, " from {} to {}", self.location, location_end)?;
|
||||||
@ -308,7 +293,12 @@ impl ParseError {
|
|||||||
}
|
}
|
||||||
impl std::fmt::Display for ParseError {
|
impl std::fmt::Display for ParseError {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
self.fmt_custom(f, None)
|
self.fmtgs(
|
||||||
|
f,
|
||||||
|
None,
|
||||||
|
&mut crate::lang::fmtgs::FormatInfo::default(),
|
||||||
|
None,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub enum ParseErrors {
|
pub enum ParseErrors {
|
||||||
@ -327,12 +317,14 @@ pub enum ParseErrors {
|
|||||||
ErrorParsingFunctionArgs(Box<ParseError>),
|
ErrorParsingFunctionArgs(Box<ParseError>),
|
||||||
MacroError(MacroError),
|
MacroError(MacroError),
|
||||||
}
|
}
|
||||||
impl ParseErrors {
|
|
||||||
|
impl FormatGs for ParseErrors {
|
||||||
fn fmtgs(
|
fn fmtgs(
|
||||||
&self,
|
&self,
|
||||||
f: &mut std::fmt::Formatter,
|
f: &mut std::fmt::Formatter,
|
||||||
info: Option<&GlobalScriptInfo>,
|
info: Option<&GlobalScriptInfo>,
|
||||||
file: Option<&super::file::File>,
|
form: &mut crate::lang::fmtgs::FormatInfo,
|
||||||
|
file: Option<&crate::parsing::file::File>,
|
||||||
) -> std::fmt::Result {
|
) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::StatementCannotStartWith(ch) => {
|
Self::StatementCannotStartWith(ch) => {
|
||||||
@ -360,17 +352,17 @@ impl ParseErrors {
|
|||||||
Self::InvalidType(name) => write!(f, "\"{name}\" is not a type."),
|
Self::InvalidType(name) => write!(f, "\"{name}\" is not a type."),
|
||||||
Self::CannotUseFixedIndexingWithThisType(t) => {
|
Self::CannotUseFixedIndexingWithThisType(t) => {
|
||||||
write!(f, "cannot use fixed-indexing with type ")?;
|
write!(f, "cannot use fixed-indexing with type ")?;
|
||||||
t.fmtgs(f, info)?;
|
t.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ".")
|
write!(f, ".")
|
||||||
}
|
}
|
||||||
Self::CannotWrapWithThisStatement(s) => {
|
Self::CannotWrapWithThisStatement(s) => {
|
||||||
write!(f, "cannot wrap with this kind of statement: ")?;
|
write!(f, "cannot wrap with this kind of statement: ")?;
|
||||||
s.fmtgs(f, info)?;
|
s.fmtgs(f, info, form, file)?;
|
||||||
write!(f, ".")
|
write!(f, ".")
|
||||||
}
|
}
|
||||||
Self::ErrorParsingFunctionArgs(parse_error) => {
|
Self::ErrorParsingFunctionArgs(parse_error) => {
|
||||||
write!(f, "error parsing function args: ")?;
|
write!(f, "error parsing function args: ")?;
|
||||||
parse_error.fmt_custom(f, file)
|
parse_error.fmtgs(f, info, form, file)
|
||||||
}
|
}
|
||||||
Self::MacroError(e) => write!(f, "error in macro: {e}"),
|
Self::MacroError(e) => write!(f, "error in macro: {e}"),
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::{path::PathBuf, thread::JoinHandle, time::Instant};
|
use std::{path::PathBuf, thread::JoinHandle, time::Instant};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
lang::{code_runnable::RScript, global_info::GSInfo, val_data::VDataEnum},
|
lang::{code_runnable::RScript, fmtgs::FormatGs, global_info::GSInfo, val_data::VDataEnum},
|
||||||
parsing::{self, file::File, parse::ScriptError},
|
parsing::{self, file::File, parse::ScriptError},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user