From 4e50cd78e66567fe13ec16b1fc6efac7417b2fc1 Mon Sep 17 00:00:00 2001 From: mrodz <79176075+mrodz@users.noreply.github.com> Date: Sun, 7 Jan 2024 14:16:13 -0800 Subject: [PATCH] add class type to file data even when not exported --- bytecode/src/file.rs | 6 ---- bytecode/src/interpreter.rs | 5 ++- compiler/src/ast/import.rs | 2 +- compiler/src/ast/math_expr.rs | 7 ++-- compiler/src/ast/type.rs | 40 ++++++++++++++-------- compiler/src/tests/modules.rs | 61 ++++++++++++++++++++++++++++++++++ examples/crashes/crash.ms | 5 +++ examples/crashes/main.ms | 3 ++ examples/crashes/other.mmm | Bin 0 -> 246 bytes examples/crashes/other.ms | 7 ++++ src/main.rs | 2 +- 11 files changed, 110 insertions(+), 28 deletions(-) create mode 100644 examples/crashes/crash.ms create mode 100644 examples/crashes/main.ms create mode 100644 examples/crashes/other.mmm create mode 100644 examples/crashes/other.ms diff --git a/bytecode/src/file.rs b/bytecode/src/file.rs index f04bc11..9e9d0f4 100644 --- a/bytecode/src/file.rs +++ b/bytecode/src/file.rs @@ -159,12 +159,6 @@ impl MScriptFile { }; functions.run_function(name, args, current_frame, callback_state, jump_callback) - - // let functions = self.functions.borrow_mut(); - - // let functions = functions.as_mut()?.get_mut(name).ok()?.run(args, current_frame, callback_state, jump_callback); - - // function.ok() } /// Get the path of the file. diff --git a/bytecode/src/interpreter.rs b/bytecode/src/interpreter.rs index 3817c37..70c2bf5 100644 --- a/bytecode/src/interpreter.rs +++ b/bytecode/src/interpreter.rs @@ -313,14 +313,13 @@ impl Program { if let Err(e) = main_ret { stdout().lock().flush()?; - eprintln!("\n******* MSCRIPT INTERPRETER FATAL RUNTIME ERROR *******\nCall stack trace:\n{e:?}\n\nPlease report this at https://github.com/mrodz/mscript-lang/issues/new\n"); + eprintln!("\n******* MSCRIPT INTERPRETER FATAL RUNTIME ERROR *******\nCall stack trace:\n{e:?}\n\nPlease report this at https://github.com/mrodz/mscript/issues/new/choose\n"); bail!("Interpreter crashed") } if stack.borrow().size() != 0 { stdout().lock().flush()?; - - eprintln!("\n******* MSCRIPT INTERPRETER STACK MISMATCH *******\nFound:\n{}\n\n... When the program should have unwinded its stack completely. This is most likely a flaw with the compiler.\n\nPlease report this at https://github.com/mrodz/mscript-lang/issues/new\n", stack.borrow()); + eprintln!("\n******* MSCRIPT INTERPRETER STACK MISMATCH *******\nFound:\n{}\n\n... When the program should have unwinded its stack completely. This is most likely a flaw with the compiler.\n\nPlease report this at https://github.com/mrodz/mscript/issues/new/choose\n", stack.borrow()); bail!("Program exited in a confused state, execution integrity has been compromised.") } diff --git a/compiler/src/ast/import.rs b/compiler/src/ast/import.rs index 3a04164..b741f50 100644 --- a/compiler/src/ast/import.rs +++ b/compiler/src/ast/import.rs @@ -221,7 +221,7 @@ impl Parser { &input.user_data().get_source_file_name(), || { format!( - "`{}` has no visible member `{maybe_property}`.\n Please ensure that:\n - This import is not cyclical (see )\n - This item is exported using the `export` keyword\n Hint: You can put shared code in a new file and import it from both origins to work around a cyclical dependency.", + "`{}` has no visible member `{maybe_property}`.\n Please ensure that:\n - This item is exported using the `export` keyword\n - This import is not cyclical (see )\n Hint: You can put shared code in a new file and import it from both origins to work around a cyclical dependency.", module_type.name().bytecode_str() ) }, diff --git a/compiler/src/ast/math_expr.rs b/compiler/src/ast/math_expr.rs index f7803c8..1b2c118 100644 --- a/compiler/src/ast/math_expr.rs +++ b/compiler/src/ast/math_expr.rs @@ -19,10 +19,9 @@ use crate::{ }; use super::{ - dot_lookup::DotChain, function::FunctionType, list::Index, map_err, - new_err, r#type::IntoType, ClassType, CompilationState, Compile, CompileTimeEvaluate, - CompiledItem, Dependencies, Dependency, FunctionArguments, TemporaryRegister, TypeLayout, - Value, + dot_lookup::DotChain, function::FunctionType, list::Index, map_err, new_err, r#type::IntoType, + ClassType, CompilationState, Compile, CompileTimeEvaluate, CompiledItem, Dependencies, + Dependency, FunctionArguments, TemporaryRegister, TypeLayout, Value, }; pub static PRATT_PARSER: Lazy> = Lazy::new(|| { diff --git a/compiler/src/ast/type.rs b/compiler/src/ast/type.rs index 38275f5..2856cb2 100644 --- a/compiler/src/ast/type.rs +++ b/compiler/src/ast/type.rs @@ -1,5 +1,10 @@ use crate::{ - ast::{class::ClassBody, new_err, value::ValToUsize, Assignment}, + ast::{ + class::{ClassBody, ClassFlags}, + new_err, + value::ValToUsize, + Assignment, + }, parser::{AssocFileData, Node, Parser, Rule}, scope::{ScopeReturnStatus, SuccessTypeSearchResult, TypeSearchResult}, CompilationError, VecErr, @@ -231,22 +236,28 @@ impl ModuleType { Rule::class => { let mut children = child.children(); - let class_flags; + let mut class_flags = None; let maybe_ident_node = children.next().unwrap(); let ident_node = if maybe_ident_node.as_rule() == Rule::ident { - continue; + maybe_ident_node } else { - class_flags = maybe_ident_node; + class_flags = Some(maybe_ident_node); children.next().unwrap() }; - let class_flags = Parser::class_flags(class_flags).to_err_vec()?; + let class_flags = if let Some(class_flags_node) = class_flags { + let class_flags = Parser::class_flags(class_flags_node).to_err_vec()?; + log::info!("ignoring flags: {class_flags:?}"); + Some(class_flags) + } else { + None + }; - if !class_flags.is_export() { - continue; - } + // if !class_flags.is_export() { + // continue; + // } let name = ident_node.as_str(); @@ -273,12 +284,14 @@ impl ModuleType { .user_data() .add_type(name.into(), ident.ty().unwrap().clone()); - log::trace!( - "Gen. mod {:?} -- adding class {name:?}", - input.user_data().source_path() - ); + if class_flags.as_ref().is_some_and(ClassFlags::is_export) { + log::trace!( + "Gen. mod {:?} -- adding class {name:?}", + input.user_data().source_path() + ); - export.add(ident); + export.add(ident); + } } Rule::assignment => { if let Ok(assignment) = Assignment::type_from_node(&child) { @@ -291,6 +304,7 @@ impl ModuleType { } } Rule::type_alias => { + // Default behavior: always added to `AssocFileData` API let ty = Parser::type_alias(child).to_err_vec()?; log::trace!( diff --git a/compiler/src/tests/modules.rs b/compiler/src/tests/modules.rs index 1eb3c2b..0d06c83 100644 --- a/compiler/src/tests/modules.rs +++ b/compiler/src/tests/modules.rs @@ -293,3 +293,64 @@ fn forward_export() { .run() .unwrap() } + +#[test] +fn dependent_hidden_type_exports() { + EvalEnvironment::entrypoint( + "main.ms", + r#" + # these functions cannot be called, because their inputs are hidden and cannot be constructed in main.ms + import take_kilometer, take_mile from other + "#, + ) + .unwrap() + .add("other.ms", r#" + type Kilometer int + class Mile {} + + export take_kilometer: fn(Kilometer) = fn(input: Kilometer) { + print input + } + + export take_mile: fn(Mile) = fn(input: Mile) { + print input + } + "#) + .unwrap() + .run() + .unwrap() +} + +#[test] +#[should_panic = "`other.ms` has no visible member `Mile`"] +fn dependent_hidden_type_exports_errors_ok() { + EvalEnvironment::entrypoint( + "main.ms", + r#" + import take_kilometer from other + + take_kilometer(5) + + # this function cannot be called, because its inputs are hidden and cannot be constructed in main.ms + import take_mile, Mile from other + take_mile(Mile()) + "#, + ) + .unwrap() + .add("other.ms", r#" + type Kilometer int + class Mile {} + + export take_kilometer: fn(Kilometer) = fn(input: Kilometer) { + assert input == 5 + } + + export take_mile: fn(Mile) = fn(input: Mile) { + # should never run + assert false + } + "#) + .unwrap() + .run() + .unwrap() +} diff --git a/examples/crashes/crash.ms b/examples/crashes/crash.ms new file mode 100644 index 0000000..b531e8c --- /dev/null +++ b/examples/crashes/crash.ms @@ -0,0 +1,5 @@ +x = "hi" + +x = [1, 2, 3] + +print x[2] \ No newline at end of file diff --git a/examples/crashes/main.ms b/examples/crashes/main.ms new file mode 100644 index 0000000..81d10e9 --- /dev/null +++ b/examples/crashes/main.ms @@ -0,0 +1,3 @@ +import function, Mile from other + +function(Mile()) \ No newline at end of file diff --git a/examples/crashes/other.mmm b/examples/crashes/other.mmm new file mode 100644 index 0000000000000000000000000000000000000000..a960bbf3c10605ecc3ad7c85a3bf5db7314cb406 GIT binary patch literal 246 zcmZvXy$S*`5QOIi6j9;OYUQjf&WKj0mA%i9A|_lQKaxw{-+1u{;hNoLnVoM|(M=oK zwp-y{A43w+2W*I;qFx$>8Rn2sg9=j|sXkyr&ECgOhQ?Z3kKAV!!}=x7g<*-)cTwCp xSB||g+C5Ulib`M5E;Bz=&aJ;EBRL;|;xeQv(f%_P|B6&{B5Ln&{*BlC&lCEcKo$T1 literal 0 HcmV?d00001 diff --git a/examples/crashes/other.ms b/examples/crashes/other.ms new file mode 100644 index 0000000..b69398a --- /dev/null +++ b/examples/crashes/other.ms @@ -0,0 +1,7 @@ +type Kilometer int + +export class Mile {} + +export function: fn(Mile) = fn(input: Mile) { + print input +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 83ba413..84e3877 100644 --- a/src/main.rs +++ b/src/main.rs @@ -229,7 +229,7 @@ fn main() -> Result<()> { println!( "{}", format!( - " Exit:\n Runner thread status: {}\n Task status: {}\n Program exit: {}\n", + " Exit:\n Runner thread status: {}\n Compilation status: {}\n Program exit: {}\n", if thread_ok { "ok" } else { "failed"}, if job_ok { "ok" } else { "failed" }, if execution_ok { "ok" } else { "failed" },