Skip to content

Commit

Permalink
Merge #128
Browse files Browse the repository at this point in the history
128: Empty blocks evaluate to nil. r=ptersilie a=ltratt

Whilst here, it is silly for `add_global` to take a `String` when both callers have to call `to_owned` for the `&str` they really have.

Note this is different behaviour from (at least) Java SOM (see SOM-st/SOM#36).

Co-authored-by: Laurence Tratt <[email protected]>
  • Loading branch information
bors[bot] and ltratt authored Jun 1, 2020
2 parents 544c3a2 + 449299a commit 5b25779
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
11 changes: 11 additions & 0 deletions lang_tests/empty_block.som
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"
VM:
status: success
stdout: nil
"

empty_block = (
run = (
[] value println.
)
)
10 changes: 8 additions & 2 deletions src/lib/compiler/ast_to_instrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,13 @@ impl<'a, 'input> Compiler<'a, 'input> {
max_stack = max(max_stack, 1);
vm.instrs_push(Instr::Return, span);
} else {
vm.instrs_push(Instr::Return, exprs.iter().last().unwrap().span());
if exprs.len() == 0 {
let idx = vm.add_global("nil");
vm.instrs_push(Instr::GlobalLookup(idx), span);
vm.instrs_push(Instr::Return, span);
} else {
vm.instrs_push(Instr::Return, exprs.iter().last().unwrap().span());
}
}
self.vars_stack.pop();

Expand Down Expand Up @@ -638,7 +644,7 @@ impl<'a, 'input> Compiler<'a, 'input> {
}
}
None => {
let name = self.lexer.span_str(*span).to_owned();
let name = self.lexer.span_str(*span);
let instr = Instr::GlobalLookup(vm.add_global(name));
vm.instrs_push(instr, *span);
}
Expand Down
8 changes: 3 additions & 5 deletions src/lib/vm/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -992,14 +992,12 @@ impl VM {

/// Add the global `n` to the VM, returning its index. Note that global names (like strings)
/// are reused, so indexes are also reused.
pub fn add_global(&mut self, s: String) -> usize {
// We want to avoid `clone`ing `s` in the (hopefully common) case of a cache hit, hence
// this slightly laborious dance and double-lookup.
if let Some(i) = self.reverse_globals.get(&s) {
pub fn add_global(&mut self, s: &str) -> usize {
if let Some(i) = self.reverse_globals.get(s) {
*i
} else {
let len = self.globals.len();
self.reverse_globals.insert(s, len);
self.reverse_globals.insert(s.to_owned(), len);
self.globals.push(Val::illegal());
len
}
Expand Down

0 comments on commit 5b25779

Please sign in to comment.