From 12e37d4335d611db0d27bfb999dd9b7a5b6f161e Mon Sep 17 00:00:00 2001 From: Nat Lasseter Date: Wed, 21 Oct 2020 19:57:14 +0100 Subject: [PATCH 1/2] Introduce the 'true' and 'false' conditions --- README.md | 3 +++ crsn/src/asm/instr/cond.rs | 11 +++++++++++ crsn/src/runtime/frame/status.rs | 2 ++ examples/test_cond.csn | 24 ++++++++++++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 examples/test_cond.csn diff --git a/README.md b/README.md index fbc4ec9..42604ae 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,8 @@ These keywords (among others) are used in conditional branches to specify flag t - `nem`, `nempty` … Not empty - `eof` … EOF - `neof` … Not EOF +- `true`, `always`, `else` … Always true +- `false`, `never` … Always false # Syntax @@ -207,6 +209,7 @@ Conditonal branches are written like this: then only one branch is taken - there is no fall-through. - The definition order is preserved, i.e. if the `inval` flag is to be checked, it should be done before checking e.g. `nz`, which is, incidentally, true by default, because most flags are cleared by instructions that affects flags. +- `else` can be used as a final choice of branch that will always be taken. ## Routines diff --git a/crsn/src/asm/instr/cond.rs b/crsn/src/asm/instr/cond.rs index c3b86d3..13ff6c9 100644 --- a/crsn/src/asm/instr/cond.rs +++ b/crsn/src/asm/instr/cond.rs @@ -106,6 +106,10 @@ pub enum Cond { Eof, /// Not empty NotEof, + // Always true, for eg. (else? ...) + True, + /// Always false + False, } pub fn parse_cond(text: &str, pos: &SourcePosition) -> Result { @@ -134,6 +138,8 @@ pub fn parse_cond(text: &str, pos: &SourcePosition) -> Result { "neof" => Cond::NotEof, "ov" => Cond::Overflow, "nov" => Cond::NotOverflow, + "true" | "always" | "else" => Cond::True, + "false" | "never" => Cond::False, _ => { return Err(CrsnError::Parse(format!("Unknown cond: {}", text).into(), pos.clone())); } @@ -174,6 +180,8 @@ impl Display for Cond { Cond::Valid => "valid", Cond::Eof => "eof", Cond::NotEof => "neof", + Cond::True => "true", + Cond::False => "false", }) } } @@ -214,6 +222,9 @@ impl Not for Cond { Cond::NotEof => Cond::Eof, Cond::Eof => Cond::NotEof, + + Cond::True => Cond::False, + Cond::False => Cond::True, } } } diff --git a/crsn/src/runtime/frame/status.rs b/crsn/src/runtime/frame/status.rs index dec3d5a..286c897 100644 --- a/crsn/src/runtime/frame/status.rs +++ b/crsn/src/runtime/frame/status.rs @@ -115,6 +115,8 @@ impl StatusFlags { Cond::NotEmpty => !self.empty, Cond::Eof => self.eof, Cond::NotEof => !self.eof, + Cond::True => true, + Cond::False => false, } } diff --git a/examples/test_cond.csn b/examples/test_cond.csn new file mode 100644 index 0000000..b4a5208 --- /dev/null +++ b/examples/test_cond.csn @@ -0,0 +1,24 @@ +( + (ld r8 0) + + (ld r0 1 + (true? (add r8 1)) + ) + + (sub r0 1 + (pos? (fault)) + (else? (add r8 1)) + ) + + (nop + (always? (add r8 1)) + ) + + (nop + (never? (fault)) + ) + + (cmp r8 3 + (ne? (fault)) + ) +) -- 2.36.2 From 0006cd06ece8dee97e67e85dbf570dbe52dd2ec6 Mon Sep 17 00:00:00 2001 From: Nat Lasseter Date: Thu, 22 Oct 2020 20:05:33 +0100 Subject: [PATCH 2/2] Reduce true/false conditionals down to just 'else' and warn if else is used in non-final branch --- crsn/src/asm/instr/cond.rs | 7 +++---- crsn/src/asm/instr/flatten.rs | 4 ++++ examples/test_cond.csn | 11 ++--------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/crsn/src/asm/instr/cond.rs b/crsn/src/asm/instr/cond.rs index 13ff6c9..5b72068 100644 --- a/crsn/src/asm/instr/cond.rs +++ b/crsn/src/asm/instr/cond.rs @@ -138,8 +138,7 @@ pub fn parse_cond(text: &str, pos: &SourcePosition) -> Result { "neof" => Cond::NotEof, "ov" => Cond::Overflow, "nov" => Cond::NotOverflow, - "true" | "always" | "else" => Cond::True, - "false" | "never" => Cond::False, + "else" => Cond::True, _ => { return Err(CrsnError::Parse(format!("Unknown cond: {}", text).into(), pos.clone())); } @@ -180,8 +179,8 @@ impl Display for Cond { Cond::Valid => "valid", Cond::Eof => "eof", Cond::NotEof => "neof", - Cond::True => "true", - Cond::False => "false", + Cond::True => "else", + Cond::False => "never", }) } } diff --git a/crsn/src/asm/instr/flatten.rs b/crsn/src/asm/instr/flatten.rs index b307b7c..d66721a 100644 --- a/crsn/src/asm/instr/flatten.rs +++ b/crsn/src/asm/instr/flatten.rs @@ -49,6 +49,10 @@ impl Flatten for InstrWithBranches { return Err(CrsnError::Asm(AsmError::ConditionalAlreadyUsed(cond), branch.pos())); } + if cnt != branch_count - 1 && cond == Cond::True { + warn!("\"Else\" conditional used in non-final branch at {}:{}", branch.pos().line, branch.pos().column); + } + let next_lbl = if cnt == branch_count - 1 { end_lbl.clone() } else { diff --git a/examples/test_cond.csn b/examples/test_cond.csn index b4a5208..fc45bce 100644 --- a/examples/test_cond.csn +++ b/examples/test_cond.csn @@ -2,7 +2,7 @@ (ld r8 0) (ld r0 1 - (true? (add r8 1)) + (else? (add r8 1)) ) (sub r0 1 @@ -10,15 +10,8 @@ (else? (add r8 1)) ) - (nop - (always? (add r8 1)) - ) - - (nop - (never? (fault)) - ) - (cmp r8 3 + (cmp r8 2 (ne? (fault)) ) ) -- 2.36.2