Skip to content

Commit

Permalink
A few fixes:
Browse files Browse the repository at this point in the history
  * Fix IN expressions
  * Fix if/elseif chains & add test
  * Fix content property access
  • Loading branch information
rdaum committed Jul 23, 2023
1 parent e51592b commit 79ad947
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 59 deletions.
3 changes: 1 addition & 2 deletions moor-bin/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
extern crate core;

use std::io;
use std::path::PathBuf;
use std::sync::Arc;

Expand All @@ -11,7 +10,7 @@ use moor_lib::db::rocksdb::LoaderInterface;
use tokio::select;
use tokio::signal::unix::{signal, SignalKind};
use tokio::sync::RwLock;
use tracing::{debug, info};
use tracing::info;

use moor_lib::db::rocksdb::server::RocksDbServer;
use moor_lib::tasks::scheduler::Scheduler;
Expand Down
79 changes: 42 additions & 37 deletions moor-lib/src/compiler/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ impl CodegenState {
pub fn generate_stmt(&mut self, stmt: &Stmt) -> Result<(), anyhow::Error> {
match stmt {
Stmt::Cond { arms, otherwise } => {
let mut end_label = None;
let end_label = self.make_label(None);
for arm in arms {
self.generate_expr(&arm.condition)?;
let else_label = self.make_label(None);
Expand All @@ -500,20 +500,15 @@ impl CodegenState {
for stmt in &arm.statements {
self.generate_stmt(stmt)?;
}
end_label = Some(self.make_label(None));
self.emit(Op::Jump {
label: end_label.unwrap(),
});
self.emit(Op::Jump { label: end_label });
self.commit_label(else_label);
}
if !otherwise.is_empty() {
for stmt in otherwise {
self.generate_stmt(stmt)?;
}
}
if let Some(end_label) = end_label {
self.commit_label(end_label);
}
self.commit_label(end_label);
}
Stmt::ForList { id, expr, body } => {
self.generate_expr(expr)?;
Expand Down Expand Up @@ -865,17 +860,17 @@ mod tests {
Imm(one),
Imm(two),
Eq,
If(0.into()),
If(1.into()),
Imm(five),
Return,
Jump { label: 1.into() },
Jump { label: 0.into() },
Imm(two),
Imm(three),
Eq,
If(2.into()),
Imm(three),
Return,
Jump { label: 3.into() },
Jump { label: 0.into() },
Imm(six),
Return,
Done
Expand Down Expand Up @@ -961,9 +956,9 @@ mod tests {
Push(x),
Imm(five),
Gt,
If(2.into()),
If(3.into()),
ExitId(0.into()),
Jump { label: 3.into() },
Jump { label: 2.into() },
Jump { label: 0.into() },
Done,
]
Expand Down Expand Up @@ -1010,12 +1005,12 @@ mod tests {
Push(x),
Imm(five),
Eq,
If(2.into()),
If(3.into()),
Exit {
stack: 0.into(),
label: 1.into()
},
Jump { label: 3.into() },
Jump { label: 2.into() },
Exit {
stack: 0.into(),
label: 1.into()
Expand Down Expand Up @@ -1954,35 +1949,40 @@ mod tests {

#[test]
fn test_scatter_precedence() {
let program = "{a,b,c} = {{1,2,3}}[1]; return {a,b,c};";
let program = "{a,b,?c, @d} = {{1,2,player:kill(b)}}[1]; return {a,b,c};";
let binary = compile(program).unwrap();
let (a, b, c) = (
let (a, b, c, d) = (
binary.find_var("a"),
binary.find_var("b"),
binary.find_var("c"),
binary.find_var("d"),
);
/*
0: 124 NUM 1
1: 016 * MAKE_SINGLETON_LIST
2: 125 NUM 2
3: 102 LIST_ADD_TAIL
4: 126 NUM 3
5: 102 LIST_ADD_TAIL
6: 016 * MAKE_SINGLETON_LIST
7: 124 NUM 1
8: 014 * INDEX
9: 112 013 003 003 004
4: 072 PUSH player
5: 100 000 PUSH_LITERAL "kill"
7: 086 PUSH b
8: 016 * MAKE_SINGLETON_LIST
9: 010 * CALL_VERB
10: 102 LIST_ADD_TAIL
11: 016 * MAKE_SINGLETON_LIST
12: 124 NUM 1
13: 014 * INDEX
14: 112 013 004 002 004
018 000 019 000 020
000 021 * SCATTER 3/3/4: a/0 b/0 c/0 21
21: 111 POP
22: 085 PUSH a
23: 016 * MAKE_SINGLETON_LIST
24: 086 PUSH b
25: 102 LIST_ADD_TAIL
26: 087 PUSH c
27: 102 LIST_ADD_TAIL
28: 108 RETURN
*/
001 021 000 028 * SCATTER 4/2/4: a/0 b/0 c/1 d/0 28
28: 111 POP
29: 085 PUSH a
30: 016 * MAKE_SINGLETON_LIST
31: 086 PUSH b
32: 102 LIST_ADD_TAIL
33: 087 PUSH c
34: 102 LIST_ADD_TAIL
35: 108 RETURN
*/

assert_eq!(
binary.main_vector,
Expand All @@ -1991,19 +1991,24 @@ mod tests {
MakeSingletonList,
Imm(1.into()),
ListAddTail,
Imm(2.into()),
Push(binary.find_var("player")),
Imm(binary.find_literal("kill".into())),
Push(b),
MakeSingletonList,
CallVerb,
ListAddTail,
MakeSingletonList,
Imm(0.into()),
Ref,
Scatter {
nargs: 3,
nreq: 3,
nargs: 4,
nreq: 2,
rest: 4,
labels: vec![
ScatterLabel::Required(a),
ScatterLabel::Required(b),
ScatterLabel::Required(c),
ScatterLabel::Optional(c, None),
ScatterLabel::Rest(d),
],
done: 0.into(),
},
Expand Down
58 changes: 58 additions & 0 deletions moor-lib/src/compiler/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,64 @@ mod tests {
);
}

#[test]
fn test_parse_if_elseif_chain() {
let program = r#"
if (1 == 2)
return 5;
elseif (2 == 3)
return 3;
elseif (3 == 4)
return 4;
else
return 6;
endif
"#;
let parse = parse_program(program).unwrap();
assert_eq!(parse.stmts.len(), 1);
assert_eq!(
parse.stmts[0],
Stmt::Cond {
arms: vec![
CondArm {
condition: Expr::Binary(
BinaryOp::Eq,
Box::new(VarExpr(v_int(1))),
Box::new(VarExpr(v_int(2))),
),
statements: vec![Stmt::Return {
expr: Some(VarExpr(v_int(5))),
}],
},
CondArm {
condition: Expr::Binary(
BinaryOp::Eq,
Box::new(VarExpr(v_int(2))),
Box::new(VarExpr(v_int(3))),
),
statements: vec![Stmt::Return {
expr: Some(VarExpr(v_int(3))),
}],
},
CondArm {
condition: Expr::Binary(
BinaryOp::Eq,
Box::new(VarExpr(v_int(3))),
Box::new(VarExpr(v_int(4))),
),
statements: vec![Stmt::Return {
expr: Some(VarExpr(v_int(4))),
}],
},
],

otherwise: vec![Stmt::Return {
expr: Some(VarExpr(v_int(6))),
}],
}
);
}

#[test]
fn test_parse_for_loop() {
let program = "for x in ({1,2,3}) b = x + 5; endfor";
Expand Down
2 changes: 1 addition & 1 deletion moor-lib/src/db/mock_world_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl WorldState for MockState {
unimplemented!()
}

fn owner_of(&mut self, obj: Objid) -> Result<Objid, ObjectError> {
fn owner_of(&mut self, _obj: Objid) -> Result<Objid, ObjectError> {
unimplemented!()
}

Expand Down
10 changes: 4 additions & 6 deletions moor-lib/src/db/rocksdb/tx_worldstate_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::model::verbs::{VerbAttrs, VerbInfo};
use crate::model::ObjectError;
use crate::tasks::command_parse::ParsedCommand;
use crate::util::bitenum::BitEnum;
use crate::var::{v_objid, Objid, Var, Variant, NOTHING};
use crate::var::{v_list, v_objid, Objid, Var, Variant, NOTHING};
use crate::vm::opcode::Binary;
use anyhow::Error;

Expand Down Expand Up @@ -108,12 +108,10 @@ impl WorldState for RocksDbTransaction {
} else if pname == "location" {
return self.location_of(obj).map(Var::from).map_err(|e| e.into());
} else if pname == "contents" {
return self
.contents_of(obj)
.map(|c| v_objid(obj))
.map_err(|e| e.into());
let contents = self.contents_of(obj)?.iter().map(|o| v_objid(*o)).collect();
return Ok(v_list(contents));
} else if pname == "owner" {
return self.owner_of(obj).map(|o| v_objid(o)).map_err(|e| e.into());
return self.owner_of(obj).map(Var::from).map_err(|e| e.into());
}

let (send, receive) = crossbeam_channel::bounded(1);
Expand Down
13 changes: 13 additions & 0 deletions moor-lib/src/var/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,19 @@ impl Var {
v_bool(l.contains(v))
}

/// 1-indexed position of the first occurrence of `v` in `self`, or `E_TYPE` if `self` is not a
/// list.
pub fn index_in(&self, v: &Var) -> Var {
let Variant::List(l) = self.variant() else {
return v_err(E_TYPE);
};

match l.iter().position(|x| x == v) {
None => v_err(E_TYPE),
Some(i) => v_int(i as i64 + 1),
}
}

binary_numeric_coercion_op!(mul);
binary_numeric_coercion_op!(div);
binary_numeric_coercion_op!(sub);
Expand Down
Loading

0 comments on commit 79ad947

Please sign in to comment.