diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 62544950..00000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -* -text diff --git a/fine/src/compiler.rs b/fine/src/compiler.rs index 05fb34e7..166beb8a 100644 --- a/fine/src/compiler.rs +++ b/fine/src/compiler.rs @@ -17,7 +17,7 @@ pub const EXTERN_USER_FIRST: usize = 100000; // But I'm not cool. #[derive(Debug, Clone, Copy)] pub enum Instruction { - Panic(usize), + Panic, BoolNot, Call(usize), @@ -173,22 +173,6 @@ impl<'a> Compiler<'a> { index } - fn inst_panic(&mut self, description: T) -> Instruction - where - T: Into, - { - let index = self.add_string(description.into()); - Instruction::Panic(index) - } - - fn push_panic(&mut self, description: T) -> usize - where - T: Into, - { - let instruction = self.inst_panic(description); - self.push(instruction) - } - fn patch(&mut self, i: usize, f: impl FnOnce(usize) -> Instruction) { let index = self.function.instructions.len(); self.function.instructions[i] = f(index); @@ -242,12 +226,12 @@ macro_rules! ice { }} } -// macro_rules! inst_panic { -// ($($t:tt)+) => {{ -// // eprintln!($($t)*); -// Instruction::Panic -// }}; -// } +macro_rules! inst_panic { + ($($t:tt)+) => {{ + // eprintln!($($t)*); + Instruction::Panic + }}; +} // macro_rules! ice { // ($compiler:expr, $tr:expr, $($t:tt)*) => {{}}; @@ -334,12 +318,11 @@ fn compile_expression(c: &mut Compiler, t: TreeRef) { TreeKind::NewObjectExpression => compile_new_object_expression(c, t, tree), TreeKind::SelfReference => compile_self_reference(c), TreeKind::UnaryExpression => compile_unary_operator(c, t, tree), - TreeKind::MatchExpression => compile_match_expression(c, tree), _ => ice!(c, t, "{tree:?} is not an expression, cannot compile"), }; if matches!(cr, None) { - c.push_panic(format!("panic compiling expression {:?}", tree)); + c.push(inst_panic!("panic compiling expression {:?}", tree)); } } @@ -359,7 +342,7 @@ fn compile_literal(c: &mut Compiler, t: TreeRef, tr: &Tree) -> CR { let index = c.add_string(result); c.push(Instruction::PushString(index)) } - Type::Error => c.push_panic(format!("compiling literal {:?}", tr)), + Type::Error => c.push(inst_panic!("compiling literal {:?}", tr)), _ => ice!(c, t, "unsupported literal type: {t:?}"), }; OK @@ -429,10 +412,10 @@ where fn compile_binary_expression(c: &mut Compiler, t: TreeRef, tr: &Tree) -> CR { let op = tr.nth_token(1)?; match op.kind { - TokenKind::Plus => compile_simple_binary_expression(c, tr, |c, t| match t { + TokenKind::Plus => compile_simple_binary_expression(c, tr, |_, t| match t { Type::F64 => Instruction::FloatAdd, Type::String => Instruction::StringAdd, - _ => c.inst_panic(format!("panic adding {}", t)), + _ => inst_panic!("panic adding {}", t), }), TokenKind::Minus => { compile_simple_binary_expression(c, tr, |_, _| Instruction::FloatSubtract) @@ -444,30 +427,30 @@ fn compile_binary_expression(c: &mut Compiler, t: TreeRef, tr: &Tree) -> CR { compile_simple_binary_expression(c, tr, |_, _| Instruction::FloatDivide) } - TokenKind::Less => compile_simple_binary_expression(c, tr, |c, t| match t { + TokenKind::Less => compile_simple_binary_expression(c, tr, |_, t| match t { Type::F64 => Instruction::LessFloat, Type::String => Instruction::LessString, - _ => c.inst_panic(format!("panic less {}", t)), + _ => inst_panic!("panic less {}", t), }), TokenKind::LessEqual => { - compile_simple_binary_expression(c, tr, |c, t| match t { + compile_simple_binary_expression(c, tr, |_, t| match t { Type::F64 => Instruction::GreaterFloat, Type::String => Instruction::GreaterString, - _ => c.inst_panic(format!("panic less equal {}", t)), + _ => inst_panic!("panic less equal {}", t), }); c.push(Instruction::BoolNot); OK } - TokenKind::Greater => compile_simple_binary_expression(c, tr, |c, t| match t { + TokenKind::Greater => compile_simple_binary_expression(c, tr, |_, t| match t { Type::F64 => Instruction::GreaterFloat, Type::String => Instruction::GreaterString, - _ => c.inst_panic(format!("panic greater {}", t)), + _ => inst_panic!("panic greater {}", t), }), TokenKind::GreaterEqual => { - compile_simple_binary_expression(c, tr, |c, t| match t { + compile_simple_binary_expression(c, tr, |_, t| match t { Type::F64 => Instruction::LessFloat, Type::String => Instruction::LessString, - _ => c.inst_panic(format!("panic greater equal {}", t)), + _ => inst_panic!("panic greater equal {}", t), }); c.push(Instruction::BoolNot); OK @@ -536,7 +519,7 @@ fn compile_binary_expression(c: &mut Compiler, t: TreeRef, tr: &Tree) -> CR { Type::F64 => Instruction::EqFloat, Type::String => Instruction::EqString, Type::Bool => Instruction::EqBool, // ? - _ => c.inst_panic(format!("panic comparing {}", arg_type)), + _ => inst_panic!("panic comparing {}", arg_type), } } }) @@ -596,11 +579,11 @@ fn compile_binary_expression(c: &mut Compiler, t: TreeRef, tr: &Tree) -> CR { } } - Declaration::ExternFunction { .. } => c.inst_panic("store ext"), - Declaration::Function { .. } => c.inst_panic("store func"), - Declaration::Class { .. } => c.inst_panic("store class"), - Declaration::ImportedModule { .. } => c.inst_panic("store import"), - Declaration::ImportedDeclaration { .. } => c.inst_panic("store import decl"), + Declaration::ExternFunction { .. } => inst_panic!("store ext"), + Declaration::Function { .. } => inst_panic!("store func"), + Declaration::Class { .. } => inst_panic!("store class"), + Declaration::ImportedModule { .. } => inst_panic!("store import"), + Declaration::ImportedDeclaration { .. } => inst_panic!("store import decl"), }; c.push(instruction); OK @@ -689,36 +672,6 @@ fn compile_load_declaration(c: &mut Compiler, t: TreeRef, declaration: &Declarat OK } -fn compile_match_expression(c: &mut Compiler, tree: &Tree) -> Option<()> { - compile_expression(c, tree.nth_tree(1)?); - - let mut patches = Vec::new(); - let match_body = tree.child_tree_of_kind(c.syntax, TreeKind::MatchBody)?; - for arm in match_body.children_of_kind(c.syntax, TreeKind::MatchArm) { - let arm = &c.syntax[arm]; - - // Evaluate pattern... - compile_pattern(c, arm.nth_tree(0)?)?; - - // ...If false jump to next arm. - let jump_next_index = c.push(Instruction::JumpFalse(0)); - - // ...If true run expression and jump out. - compile_expression(c, arm.nth_tree(2)?); - patches.push(c.push(Instruction::Jump(0))); - - c.patch(jump_next_index, |i| Instruction::JumpFalse(i)); - } - c.push_panic("Fell through all match arms"); - - // Patch the jumps to the end of the match expression. - for patch in patches { - c.patch(patch, |i| Instruction::Jump(i)); - } - - OK -} - fn compile_is_expression(c: &mut Compiler, tree: &Tree) -> Option<()> { compile_expression(c, tree.nth_tree(0)?); @@ -813,7 +766,7 @@ fn compile_type_expr_eq(c: &mut Compiler, t: TreeRef) { }; if result.is_none() { - c.push_panic(format!("panic compiling type expression eq {:?}", tree)); + c.push(inst_panic!("panic compiling type expression eq {:?}", tree)); } } @@ -924,7 +877,7 @@ fn compile_argument(c: &mut Compiler, tree: &Tree) -> CR { fn compile_new_object_expression(c: &mut Compiler, t: TreeRef, tree: &Tree) -> CR { // We pass in the arguments.... by... field order? let Type::Object(mid, ct, _) = c.semantics.type_of(t) else { - c.push_panic("new obj not ob"); + c.push(inst_panic!("new obj not ob")); return OK; }; @@ -1010,7 +963,7 @@ fn compile_member_access(c: &mut Compiler, t: TreeRef, tree: &Tree) -> CR { class.static_env.clone() } _ => { - c.push_panic("cannot get environment of {typ}"); + c.push(inst_panic!("cannot get environment of {typ}")); return None; } }; @@ -1065,7 +1018,7 @@ fn compile_statement(c: &mut Compiler, t: TreeRef, gen_value: bool) { _ => ice!(c, t, "unsupported statement tree kind {:?}", tree.kind), }; if matches!(cr, None) { - c.push_panic(format!("stat {:?}", tree)); + c.push(inst_panic!("stat {:?}", tree)); } } diff --git a/fine/src/vm.rs b/fine/src/vm.rs index 032a8c7e..91660a03 100644 --- a/fine/src/vm.rs +++ b/fine/src/vm.rs @@ -10,8 +10,8 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum VMErrorCode { - #[error("code panic (syntax or semantic error): {0}")] - Panic(Rc), + #[error("code panic (syntax or semantic error)")] + Panic, #[error("internal error: stack underflow")] StackUnderflow, #[error("internal error: stack type mismatch: {0:?} is not {1:?}")] @@ -394,12 +394,7 @@ fn eval_one( stack: &mut Vec, ) -> Result { match instruction { - Instruction::Panic(index) => { - let v = f - .get_string(index) - .unwrap_or_else(|_| "!!panic string out of range!!".into()); - return Err(VMErrorCode::Panic(v)); - } + Instruction::Panic => return Err(VMErrorCode::Panic), Instruction::BoolNot => { let value = f.pop_bool()?; f.push_bool(!value); diff --git a/fine/tests/expression/alternates.fine b/fine/tests/expression/alternates.fine index 27aae472..43eb5faf 100644 --- a/fine/tests/expression/alternates.fine +++ b/fine/tests/expression/alternates.fine @@ -59,7 +59,7 @@ fun attack(weapon: MeleeWeapon or RangedWeapon, monster: Monster, distance: f64) // `and` that follows the declaration in the `is` still has the variables // from the `is` binding in scope. if weapon is MeleeWeapon and distance > 1 or - weapon is w:RangedWeapon and (distance < w.minRange or distance > w.maxRange) { + weapon is w : RangedWeapon and (distance < w.minRange or distance > w.maxRange) { print("You are out of range"); return } @@ -127,12 +127,6 @@ fun test() -> f64 { sum = sum + v; } - let it = new Iterator { current: 0 }; - sum = sum + match it.next() { - v:f64 -> 100, - _ -> 1000, - }; - // Unroll by hand... let it = new Iterator { current: 0 }; while true { @@ -147,6 +141,5 @@ fun test() -> f64 { // like the above. } -// @ignore not finished yet, still compiler bugs -// @no-errors -// @eval: Float(90.0) \ No newline at end of file +// @ignore never finished compiling `match` +// @no-errors \ No newline at end of file