Minor "else" improvements
- Do not generate s.never to skip Else branch - Add Display impl to SourcePosition - Correct SourcePositions pointing to the end of a parsed expr instead of the beginning - Remove 'true', 'always', 'false' and 'never' from README.md
This commit is contained in:
@@ -98,8 +98,7 @@ 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
|
||||
- `else` … Always true, may be used in the last branch
|
||||
|
||||
# Syntax
|
||||
|
||||
|
||||
@@ -19,6 +19,12 @@ pub struct SourcePosition {
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
impl fmt::Display for SourcePosition {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
write!(f, "{}:{}", self.line, self.column)
|
||||
}
|
||||
}
|
||||
|
||||
/// Since errors are the uncommon case, they're boxed. This keeps the size of
|
||||
/// structs down, which helps performance in the common case.
|
||||
///
|
||||
|
||||
@@ -331,10 +331,11 @@ fn parse_sexp(s: &str, pos: &mut usize) -> ERes<Sexp> {
|
||||
//trace!("parse_sexp {}", pos);
|
||||
zspace(s, pos)?;
|
||||
let (c, _) = peek(s, *pos)?;
|
||||
let pos0 = *pos;
|
||||
let r = if c == '(' {
|
||||
Ok(Sexp::List(parse_list(s, pos)?, spos(s, *pos)))
|
||||
Ok(Sexp::List(parse_list(s, pos)?, spos(s, pos0)))
|
||||
} else {
|
||||
Ok(Sexp::Atom(parse_atom(s, pos)?, spos(s, *pos)))
|
||||
Ok(Sexp::Atom(parse_atom(s, pos)?, spos(s, pos0)))
|
||||
};
|
||||
zspace(s, pos)?;
|
||||
r
|
||||
|
||||
@@ -50,7 +50,7 @@ impl Flatten for InstrWithBranches {
|
||||
}
|
||||
|
||||
if cnt != branch_count - 1 && cond == Cond::True {
|
||||
warn!("\"Else\" conditional used in non-final branch at {}:{}", branch.pos().line, branch.pos().column);
|
||||
warn!("\"Else\" conditional used in non-final branch at {}", branch.pos());
|
||||
}
|
||||
|
||||
let next_lbl = if cnt == branch_count - 1 {
|
||||
@@ -68,11 +68,13 @@ impl Flatten for InstrWithBranches {
|
||||
// optimization for single-branch conditionals with a single instruction
|
||||
ops.push(Op { cond: Some(cond), pos: pos.clone(), kind: flattened.remove(0).kind });
|
||||
} else {
|
||||
ops.push(Op {
|
||||
kind: OpKind::BuiltIn(BuiltinOp::Jump(next_lbl.clone())),
|
||||
pos: pos.clone(),
|
||||
cond: Some(!cond),
|
||||
});
|
||||
if cond != Cond::True { // evoid emiting `op.never`
|
||||
ops.push(Op {
|
||||
kind: OpKind::BuiltIn(BuiltinOp::Jump(next_lbl.clone())),
|
||||
pos: pos.clone(),
|
||||
cond: Some(!cond),
|
||||
});
|
||||
}
|
||||
ops.extend(flattened);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,11 +50,15 @@ impl OpTrait for Op {
|
||||
OpKind::Ext(op) => op.to_sexp()
|
||||
};
|
||||
|
||||
// TODO rewrite to be more readable?
|
||||
if let Some(cond) = self.cond {
|
||||
if let Sexp::List(items, _) = &mut se {
|
||||
if let Some(Sexp::Atom(Atom::S(s), _)) = &mut items.get_mut(0) {
|
||||
s.push('.');
|
||||
s.push_str(&cond.to_string());
|
||||
// "true" is used for "else" branches, it has no effect - just omit it
|
||||
if cond != Cond::True {
|
||||
if let Sexp::List(items, _) = &mut se {
|
||||
if let Some(Sexp::Atom(Atom::S(s), _)) = &mut items.get_mut(0) {
|
||||
s.push('.');
|
||||
s.push_str(&cond.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
(
|
||||
; test else
|
||||
|
||||
(cmp 0 5
|
||||
(eq? (fault))
|
||||
(else? (ld r0 15))
|
||||
(lt? (fault)) ; This should produce a warning
|
||||
)
|
||||
(cmp 15 r0
|
||||
(ne? (fault "else did not run")))
|
||||
|
||||
(ld r0 0)
|
||||
|
||||
(cmp 0 5
|
||||
(lt? (nop))
|
||||
(else? (fault "fallthrough to else"))
|
||||
)
|
||||
|
||||
;
|
||||
|
||||
(ld r8 0)
|
||||
|
||||
(ld r0 1
|
||||
|
||||
Reference in New Issue
Block a user